2015-04-29 15 views
14

Próbuję zbudować bardzo prostą aplikację Todo w React Native. Składa się z dwóch widoków: jednego z listą zadań, jednego z polem wprowadzania (w celu dodania nowego). Nawigacja jest zapewniona przez NavigatorIOS i przyciski na niej (które mogłyby być UIBarButtonItem z UIKit).Manipulowanie trasą NavigatorIOS na komponencie

W widoku listy, istnieje Dodaj prawym przyciskiem Navigator, na widoku z pola tekstowego, tam z tyłu przycisk po lewej i Sporządzono jeden po prawej stronie. Po kliknięciu na gotowe, powinno dodać nowe zadanie z treścią pola tekstowego.

Problem to, przyciski i ich działania są zdefiniowane podczas tworzenia komponentu NavigatorIOS i nie znajduję sposobu na dołączenie metody zdefiniowanej w innym komponencie jako akcji przycisku.

Jako przykład, tu jest mój NavigatorIOS

class TodoList extends Component { 

    render() { 
     return (
      <NavigatorIOS 
       ref="nav" 
       style={styles.navbar} 
       initialRoute={{ 
        component: ItemList, 
        title: 'Todo list', 
        rightButtonTitle: 'Add', 
        onRightButtonPress:() => { 
         this.refs.nav.push({ 
          title: 'Add a new task', 
          component: AddTodo, 
          rightButtonTitle: 'Done', 
          onRightButtonPress:() => { 
           console.log('done !'); 
          } 
         }); 
        } 
       }} 
      /> 
     ); 
    } 
} 

nie umieścić tutaj moje dwie inne składniki ItemList i AddTodo jak nie ma nic ciekawego na nim.

Potrzebuję sposobu, aby komponenty komunikowały się (jak w schemacie delegowania) z komponentem nawigacji.

Być może nie jest to możliwe lub całkowicie pomijam paradygmat używany w React Native, więc nie krępuj się, jeśli coś nie jest jasne na moje pytanie.

Edycja 05/26

Właściwie Facebook zespół jest świadomy, że czegoś brakuje, aby obsłużyć ten przypadek użycia z NavigatorIOS komponentu.

Od Eric Vicenti (opublikowanej 3 lutego 2015 r.) Na an issue on GitHub, która dokładnie obejmuje moje pytanie.

Obecnie najlepszym sposobem na to jest stworzenie EventEmitter w właściciela NavigatorIOS, potem można przekazać go dzieciom korzystania route.passProps. Dziecko może mieszać w Subscribable.Mixin a następnie w componentDidMount, może

this.addListenerOn(this.props.events, 'myRightBtnEvent', this._handleRightBtnPress); 

Jest oczywiste, że ten API wymaga poprawy ty. Aktywnie pracujemy nad routingowym interfejsem API w Relay i mamy nadzieję, że router reaguje, ale chcemy, aby NavigatorIOS był niezależnie wykorzystywany. Może powinniśmy dodać emitera zdarzeń wewnątrz obiektu navigator, więc elementy dziecko może zapisać się do różnych aktywności Navigator:

this.addListenerOn(this.props.navigator.events, 'rightButtonPress', this._handleRightBtnPress); 
+0

mam napotkasz dokładnie ten sam problem i architektury rozwiązali go poprzez rozszerzenie NavigationBar taki sposób, że można zdefiniować działania w składniku dziecięcej. Zbadałem również możliwość wykorzystania zdarzeń, które sprawiają, że rodzic emituje zdarzenia z menu kliknięć, a dziecko może słuchać wydarzeń i podejmować działania, nie będąc pewnymi, czy jest to właściwe podejście, zainteresowane tym, co mówią inni. –

+0

@AaronSaunders Dziękuję za Twój komentarz! Czy rozszerzyłeś 'NavigatorIOS' lub' NavigationBar' jest wewnętrznym składnikiem 'NavigatorIOS'? Próbowałem rozszerzyć nawigator, ale ponieważ wywołania zwrotne są na podpowiedzie 'initialRoute' (i głębiej), nie rozumiem, jak je narazić. – Blackus

Odpowiedz

1

A. W początkowej składnika

this.props.navigator.push({ 
    title: 'title', 
    component: MyComponent, 
    rightButtonTitle: 'rightButton', 
    passProps: { 
     ref: (component) => {this.pushedComponent = component}, 
    }, 
    onRightButtonPress:() => { 
     // call func 
     this.pushedComponent && this.pushedComponent.myFunc(); 
    }, 
}); 

B. W pchnął składnik
zamień onRightButtonPress w komponent pchnięty.

componentDidMount: function() { 
    // get current route 
    var route = this.props.navigator.navigationContext.currentRoute; 
    // update onRightButtonPress func 
    route.onRightButtonPress = () => { 
     // call func in pushed component 
     this.myFunc(); 
    }; 
    // component will not rerender 
    this.props.navigator.replace(route); 
}, 
Powiązane problemy