2013-02-02 14 views
8

Poszukuję rozwiązania do wiązania atrybutu obiektu zawierającego tablicę ciągów (reprezentującą wyliczenie na serwerze) do listy pól wyboru . Wiązanie powinno być dwukierunkowe.Wiązanie dwukierunkowe między tablicą atrybutów obiektu (wylicz na serwerze) i grupą pól wyboru embera

Na serwerze mamy pewne wyrażenie enum, np. Rola z wartościami "ADMIN", "GUEST", "USER". Obiekt użytkownik może mieć zatem kilka ról, co obiekt użytkownika w Ember ma postać

App.User = Ember.Object.create({ 
    roles: ["USER", "ADMIN"] 
}); 

W podawania użytkownika, powinna być grupą wyboru. Jedno pole wyboru na rolę. Można więc wybrać none, all lub kilka.

Wiem, że istnieje widok Ember.Checkbox, który można wykorzystać do tego. To, czego szukam, to łatwy i ogólny widok do obsługi wszelkiego rodzaju wyliczeń, jak wspomniano powyżej.

Zatem pytania:

  • ma ktoś miły rozwiązanie tego problemu?
  • Czy ktoś zna projekt typu open source, zapewniający takie rozszerzenia ember?

Z góry dziękuję. // ph

Odpowiedz

8

Ogólny sposób obsługiwać dwukierunkowy wiązania pomiędzy obiektem Ember i checkbox może być realizowane za pomocą zwykłego ember.js bez konieczności jakichkolwiek wtyczek, jeśli są chętni do synchronizowania stałe teksty na serwerze i kliencie ręcznie (przy użyciu AJAX lub WebSockets). Zauważ, że Ember może automatycznie aktualizować listę opcji przy pomocy Checkbox po synchronizacji.

Więc odtąd będę zakładać, że masz am enum z ról jako tablica Ember:

App.Roles = [ "USER", "ADMIN", "GUEST" ]; 

Następnie pokażemy opcje dostępne dla użytkownika w CollectionView tak (szablon jest podana poniżej).

OptionsView = Em.CollectionView.extend({ 
    contentBinding: 'App.Roles', // Show a list of _all_ available roles 
    userBinding: 'App.User',  // This points to the active user 
    tagName: 'ul',    // Shown as a <ul> 
    itemViewClass: Em.View.extend({ 
     userBinding: 'parentView.user', // For convenience 
     templateName: 'user-roles' // Defined later 
    }) 
}); 

Szablon dla każdej opcji jest:

<script data-template-name="user-roles" type="text/x-handlebars"> 
    <label> {{view App.RoleCheckbox 
      contentBinding="view.content"}} 
    {{view.content}} 
    </label> 
</script> 

pamiętać, że korzystanie z <label> tagu zapewnia, że ​​click zdarzenie pole wyboru jest zwolniony na kliknięcie w dowolnym miejscu na etykiecie.

Wreszcie App.RoleCheckbox jest rozszerzeniem klasy Ember.Checkbox który uchwyty checked nieruchomość i click wydarzenie, aby przełączyć rolę:

App.RoleCheckbox = Em.Checkbox.extend({ 
    userRolesBinding: 'parentView.user.roles', // Points to the roles of the user 

    checked: function() { 
     var userRoles = this.get('userRoles'); 
     return userRoles.contains(this.get('content')); 
    }.property('content', '[email protected]'), 

    click: function (evt) { 
     var isPresent = this.get('checked'), 
      userRoles = this.get('userRoles'), 
      role  = this.get('content'); 

     if (!isPresent) { 
      userRoles.pushObject(role); 
     } else { 
      userRoles.removeObject(role); 
     } 
    } 
}); 

Przykład roboczy to: http://jsfiddle.net/BLQBf/ (Spójrz na konsoli, aby zobaczyć komunikaty dziennika)

Należy zauważyć, że nie jest to całkowicie Ember-esque, ponieważ widok wykonuje część zadania przeznaczoną dla controller. Idealnie byłoby, gdyby zdarzenie click wywoływało funkcję na RoleCheckboxController, która powodowałaby zmiany obiektu User.

+1

dziękuje @musically_ut za odpowiedź. Musiałem odłożyć na później moją implementację, więc mój komentarz się spóźnia.Twoje rozwiązanie działa, ale był mały problem. Obserwator na "sprawdzonym" wyzwala przed zdarzeniem kliknięcia. Tam musiałem przywrócić instrukcję if-else wywołaną przez zdarzenie click. –

+0

@musically_ut, zadałem pytanie, jak wykonać połączenie z RoleCheckboxController zgodnie z sugestią [tutaj] (http://stackoverflow.com/questions/16281401/ember-how-to-create-and-binda-a- checkbox-kontroler), ale nie mogłem go uruchomić. – lauhub

+0

wywołał już edycję odpowiedzi @musically_ut. Obecnie jest recenzowany. Do czasu przeglądu. użyj zdarzenia "zmień" zamiast zdarzenia "kliknięcie" ze względu na zgodność przeglądarki. Zobacz także https://github.com/emberjs/ember.js/issues/2604 –

Powiązane problemy