2013-10-29 26 views
0

我認爲我提出這個問題的方式誤導了你,所以我做了一個主要的編輯。 我將使用代碼knockoutjs教程KnockoutJS綁定應用於我的ViewModel實際創建之前

「加載和保存數據」,第3步

我做了一個變化,以顯示我的意思。

function Task(data) { 
    this.title = ko.observable(data.title); 
    this.isDone = ko.observable(data.isDone); 
} 

function TaskListViewModel() { 
    // Data 
    var self = this; 
    self.tasks = ko.observableArray([]); 
    self.newTaskText = ko.observable(); 
    self.incompleteTasks = ko.computed(function() { 
     return ko.utils.arrayFilter(self.tasks(), function(task) { return !task.isDone() }); 
    }); 

    // Operations 
    self.addTask = function() { 
     self.tasks.push(new Task({ title: this.newTaskText() })); 
     self.newTaskText(""); 
    }; 
    self.removeTask = function(task) { self.tasks.remove(task) }; 

    // ** Read this!! 
    // This below is the original code in the tutorial, used to fetch remote data. 
    // I commented this out, and i will use the below load() method instead. 
    // ** 
    //$.getJSON("/tasks", function(allData) { 
    // var mappedTasks = $.map(allData, function(item) { return new Task(item) }); 
    // self.tasks(mappedTasks); 
    //}); 

    // This is the load method to emulate the above commented 
    // $.get. Please, DO NOT CARE about the implementation, or 
    // the setTimeout usage, etc., this method ONLY EXISTS TO 
    // EMULATE A SLOW SERVER RESPONSE. 
    // So, we have to ways of using it: 
    //  - load('slow'), will set result after 1 second 
    //  - any other argument will set result instantly. 
    self.load = function(howFast) { 
     if (howFast == 'slow') { 
      setTimeout(function(){ 
       mappedTasks = []; 
       mappedTasks.push(new Task({ 
        title: 'Some task slowly loaded from server', 
        isDone: false 
       })); 
      }, 1000); 
     } else { 
      mappedTasks = []; 
      mappedTasks.push(new Task({ 
       title: 'Some task quick!', 
       isDone: false 
      })); 
     } 
    } 

    // Now please note this: 
    // - if i use load(), mappedTask is instant updated and 
    // everything runs fine 
    // - if i use load('slow'), mappedTask is updated AFTER 
    // VALUES ARE BOUND, so if you open your browser console 
    // you will see an "Uncaught ReferenceError: mappedTasks is not defined" error. 
    self.load(); 
    self.tasks(mappedTasks); 
} 


ko.applyBindings(new TaskListViewModel()); 

問題:綁定應用視圖模型已經與initializazions完成的,因此造成的錯誤。我認爲我在代碼評論中提供了足夠的細節,問我是否認爲你需要更多。無論如何,我有點驚訝以前沒有人碰到過這個東西,所以我錯過了這裏非常重要的東西嗎?

問題:如何避免這種情況?

Fiddle

+0

我沒有在使用了一段時間的淘汰賽,我可能會被誤解:http://jsfiddle.net/cjuZZ/1/ –

回答

0

您有一個HTML錯誤。

您的setTimeout函數試圖以編程方式將所選選項設置爲不在列表中的選項。瀏覽器無法做到這一點,所以選擇保持原樣。

http://jsfiddle.net/UD89R/6/

function ViewModel() { 
    // Setup something. 
    var self = this; 
    self.foo = ko.observable(); 
    self.options = ko.observableArray([{id:1, name:'Homer'}, {id:2, name:'Barney'}]); 

    // Make a lot of async data load, like  
    // $.get('this', function(){ /* Process data */ }); 
    // $.get('that', anotherHandler); 
    // $.get('somethingElse', self.someObservable); 

    // Assume the whole process would take 1 second. 
    setTimeout(function(){ 
     self.options.push({id: 3, name: 'Grimes'}); 
     self.foo(3); 
     // Too late! foo has been overriden by the select-options binding, 
     // so this one will not log 'Grimes' as expected. 
     console.log('Loading done, check foo value:' + self.foo()); 
    }, 1000);  
} 
+0

我的問題是不是與選擇的選項,這是關於後期約束問題 – brazorf

相關問題