2014-01-13 3 views
1

Хорошо, новичок Нокаут вопрос здесь.Knockout.js - Как переключаться между видами

В этом примере: http://learn.knockoutjs.com/WebmailExampleStandalone.html#Inbox

Как вид детали почты заменить вид списка папок?

То есть, какая особенность приводит к переключению divs? При проверке dom я вижу, что происходит то, что div на самом деле отображается пустым, когда не отображается.

Может кто-нибудь просветить меня? Я знаю, что это довольно основательно, но его последний кусок мне нужно щелкнуть на месте для моего понимания.

Просто, чтобы быть на 100% понятным: когда вы нажимаете на строку в списке папок, что приводит к опустошению вида папки и отображению сведений о почте? Это привязка with? (Это не кажется правильным.)

ответ

1

Вы на правильном пути с with связывания: в этом примере виды изменяются с помощью with связывания ретрансляции на этом feature of the binding:

with связывания будет динамически добавить или удалить потомков элементов в зависимости от того, является ли соответствующее значение null/undefined или не

Так в коде ViewModel вы увидите что-то вроде это:

this.get('#:folder', function() { 
    self.chosenFolderId(this.params.folder); 
    self.chosenMailData(null); 
    $.get("/mail", { folder: this.params.folder }, self.chosenFolderData); 
}); 

this.get('#:folder/:mailId', function() { 
    self.chosenFolderId(this.params.folder); 
    self.chosenFolderData(null); 
    $.get("/mail", { mailId: this.params.mailId }, self.chosenMailData); 
}); 

Так функция, которые «цепная» Взгляд аннулирует из одного из свойств при заполнении других, который переключает взгляды, определенные как:

<!-- Chosen mail --> 
    <div class="viewMail" data-bind="with: chosenMailData"> 
    ... 
    <div/> 

<!-- Mails grid --> 
    <table class="mails" data-bind="with: chosenFolderData"> 
    </table> 

Это не приятное решение но не забывайте, что Knockout представляет собой библиотеку Databind/MVVM, а не полноценную инфраструктуру SPA, поэтому у нее нет концепций для компоновки и представления более высокого уровня.

Однако это можно было бы сделать лучше с помощью template binding:

<div id="mainView" data-bind="{template: {name: templateName, data: activeView}}"> 
</div> 

И, повернувшись взгляды в шаблоны:

<script type="text/html" id="ChosenMail"> 
    <div class="viewMail"> 
    ... 
    <div/> 
</script> 

<script type="text/html" id="MailsGrid"> 
    <table class="mails"> 
    ... 
    </table> 
</script> 

И в маршрутизации только установить activeView свойство и поиска по шаблону наименование для него:

this.get('#:folder', function() { 
    $.get("/mail", { folder: this.params.folder }, function(data) { 
     self.activeView(data); 
     self.templateName('ChosenMail'); 
    });; 
}); 

this.get('#:folder/:mailId', function() { 
    $.get("/mail", { mailId: this.params.mailId }, function(data) { 
     self.activeView(data); 
     self.templateName('MailsGrid'); 
    }); 
}); 

Но, поскольку это довольно ручная и подверженная ошибкам работа, я бы использовал что-то вроде Durandal.js, которое является настоящей системой SPA и было разработано для подобных сценариев.

1

Это просто демо-сценарий с облегченным сценарием SPA, привязка with - это просто привязка к встроенному шаблону. Не очень полезно для динамического SPA. Как и Nemesv, вы можете использовать привязку к шаблону.

Проблема с привязкой шаблона является то, что его очень многословным использовать, я обратился к этому в моей Binding библиотеке конвенции (один из многих функций)

Вместо того чтобы делать

<div id="mainView" data-bind="{template: {name: templateName, data: activeView}}"> 
</div> 

Вы делаете

<div id="mainView" data-name="activeView"> 
</div> 

Моя библиотека сделает все остальное, проверьте вики на шаблонах здесь

https://github.com/AndersMalmgren/Knockout.BindingConventions/wiki/Template-convention

И немного скрипки http://jsfiddle.net/xJL7u/11/

Смежные вопросы