1

這是我使用綁定到一個文本框代碼:值未綁定到Ko.observable在knockout.js

var CategoryViewModel = { 
    categoryModel: ko.observable({ 
     categoryId: ko.observable(), 
     categoryName: ko.observable(), 
     active: ko.observable() 
    }), 
    GetCategoryById: function (data, event) { 
     CategoryViewModel.ClickId(event.target.id); 
     var ajaxUrl = ApplicationRootUrl("GetCategoryById", "Category") + "/" + CategoryViewModel.ClickId(); 

     $.ajax({ 
      type: "GET", 
      contentType: "application/json; charset=utf-8", 
      url: ajaxUrl, 
      dataType: "json", 
      success: function (data) { 
       if (data.isSuccess) { 
        // This value got bind to textbox 
        CategoryViewModel.categoryModel(data.data); 
       } 
      }, 
      error: function (err) { 

      } 
     }); 
    }, 
    CategoryAddButton: function() { 
     CategoryViewModel.categoryModel(); 
     $('#addCategoryModel').modal('toggle'); 
    }    
}; 

$(document).ready(function() { 
    ko.applyBindings(CategoryViewModel, document.getElementById("categoryMain")); 
}); 

CategoryAddButton方法被調用按鈕的點擊。我試圖在這個方法中清空模型的值。

下面是HTML:

<input type="text" name="CategoryName" class="form-control" placeholder="Enter Category Name" data-bind="textinput: categoryModel().categoryName"> 

的文本框的值獲取綁定的ajax調用。但是,調用CategoryAddButton方法後,該值不會綁定到文本框。

回答

3

首先,我建議你使用不同的方法從你寫的內容創建視圖模型。儘管一些初學者的例子也是如此,但這只是爲了簡單 - 實際上,將視圖模型創建爲對象文字通常不是一個好主意。這是因爲在發佈here,herehere以及許多其他重複項中,訪問同一對象的另一個屬性可能會非常骯髒,儘管該任務應該是多麼微不足道。

因此,要解決這個問題,您應該使用構造函數和new運算符來代替,因爲這可以使您更容易地操作對象。不過,我已經添加了這個僅僅作爲指導你寫清晰的代碼,使用構造函數和對象語法不會單獨解決問題。

讓我們回到你的問題。要找出你的代碼無法工作的原因,看看你在綁定工作時如何處理數據,以及如何處理數據。

你說過,AJAX調用成功後,值得到了正確更新,所以綁定工作。這是因爲在AJAX調用的success回調中,實際上是將一個對象傳入categoryModel。然而,我會指出,你傳遞給它的不是一個可觀察對象,而只是一個普通對象,而你最初創建它的屬性是可觀察對象!所以即使在那裏,你也可能遇到問題。

你還說過點擊按鈕後,值沒有更新。我不確定你甚至想在這裏實現什麼;你想要顯示什麼以及數據來自哪裏?因爲這行代碼你寫的:

CategoryViewModel.categoryModel(); 

僅僅是一個getter - 它不會改變對象以任何方式,你只是在閱讀它的價值。如果不實際修改它,當然沒有什麼會改變。

所以,我會給你一個實現整個事情的可能方式,並且我建議你閱讀更多有關JavaScript對象構造函數以及如何正確使用knockout的知識。

function categoryViewModel() { 
    var self = this; 

    // Don't wrap these in another observable, that's totally needless. 
    this.categoryId = ko.observable(null); 
    this.categoryName = ko.observable(null); 
    this.active = ko.observable(true); 

    // You could actually define this on the prototype 
    // but I don't want to make it even more complicated 
    this.GetCategoryById = function(categoryId) { 
     // You could do this if the value passed can either be a plain value 
     // or an observable; ko will return the actual value to you. 
     var catId = ko.utils.unwrapObservable(categoryId); 

     var ajaxUrl = ApplicationRootUrl("GetCategoryById", "Category") + "/" + catId; 

     $.ajax({ 
      type: 'GET', 
      contentType: "application/json; charset=utf-8", 
      url: ajaxUrl, 
      dataType: "json", 
      success: function(data) { 
       if (data.isSuccess) { 
        // Correct the object references according to 
        // the structure of the response if needed. 
        self.categoryId(data.data.id); 
        self.categoryName(data.data.name); 
        self.active(data.data.isActive); 
       } 
      }, 
      error: function(err) { 
      } 
     }); 
    }; 

    this.CategoryAddButton = function() { 
     self.categoryId(null); 
     self.categoryName(null); 
     self.isActive(true); // If you want to default to true. 
     $('#addCategoryModel').modal('toggle'); 
    }; 
}; 

$(document).ready(function() { 
    ko.applyBindings(new categoryViewModel(), document.getElementById("categoryMain")); 
}); 

而你的HTML可能是:

<input type="text" name="CategoryName" class="form-control" data-bind="textInput: categoryName" /> 

對於GetCategoryById功能,它甚至會更好,如果你分配一個給函數的原型,而不是各分配一個「複製」和創建每個對象。但是因爲我認爲你只會有1個你的視圖模型的實例,所以我現在認爲它超出了範圍。