在JavaScript中声明动态的Knockout可观察对象

4
我正在将knockout与asp.net mvc结合使用,其中我在asp.net mvc中拥有一个视图模型。我有一个基于服务器端生成的数组列表,该列表基于asp.net mvc视图模型中每个类的属性名的值。例如:Array[] propertyName = { name1, name2, name3 }。现在我需要将所有这些属性名设置为可观察对象,如下所示。我可以在JavaScript中逐个输入它,但问题是它应该根据在asp.net mvc定义的视图模型中可用的属性进行动态设置。现在我正在硬编码name1、name2和name3,但我不知道如何根据从服务器返回的数组使其动态化。

<script>
  function TestViewModel() {
    var self = this;
    self.name1 = ko.observable('@name1') //from view model (need to be dynamic)
    self.name2 = ko.observable('@name2') //from view model (need to be dynamic)
    self.name3 = ko.observable('@name3') //from view model (need to be dynamic)
    
    self.btn1 = ko.observable(false); //hardcoded base on html
    self.btn2 = ko.observable(true); //hardcoded base on html
  }
  
    ko.applyBindings(new TestViewModel());
</script>


// What i expect
<script>
  function TestViewModel() {
    var self = this;
    Array[] propertyName = { name1, name2, name3 } // value retrieve from server
    @foreach(var item in propertyName) {
      // and knockout js can run this
      self.@propertyName = ko.observable(@propertyName)
    }
    
    self.btn1 = ko.observable(false); //hardcoded base on html
    self.btn2 = ko.observable(true); //hardcoded base on html
  }
  
    ko.applyBindings(new TestViewModel());
</script>

// fail because self.@propertyName
self.@propertyName = ko.observable(@propertyName)
= expected identifer
ko expected;


你尝试了什么,有什么问题? - haim770
假设有一个单一变量@@propertyName = name1,self.anystring = ko.applyBindings(@@propertyName)是可行的,但是self.@@propertyName = ko.applyBindings(@@propertyName)会出现语法错误。我希望左边也能动态化。 - Johnny88
@haim770 无法将服务器上的动态属性分配给 lhs。 - Johnny88
你可以尝试使用 self.@(PropertyName) = ... 或者 self['@PropertyName'] = ... - haim770
虽然我不清楚你将如何编写data-bind属性,如果你事先无法预料到已知的视图模型结构。 - haim770
2个回答

0
在这种情况下,您应该在页面加载时调用服务器。例如:
function TestViewModel() {
    var self = this;
    self.items = ko.observableArray();

    //call server to load the items
    $.ajax({
       url: 'someUrl',
       data: 'someValueFromTheView'
    }).done(function (result) {
        self.items(result);

    });
};

//run the bindings when the page is loaded
$(function () {
   ko.applyBindings(new TestViewModel());
});

0

您可以使用ko.mapping插件基于您的模型属性创建ko.observables。

假设您有一个将传递给Razor视图的以下模型:

 public class PersonVM
 {
    public int Id { get; set; }
    public String Name { get; set; }
    public String Address { get; set; }
 }

然后您可以将模型序列化为JSON对象,并将其传递给TestViewModel函数,使用ko.mapping.fromJs(data,{},this)将C#模型属性映射到客户端knockout视图模型observables。

<script type="text/javascript">
        function TestViewModel(data) {
            var self = this;
            ko.mapping.fromJS(data, {}, this);
            self.btn1 = ko.observable(false); //hardcoded base on html
            self.btn2 = ko.observable(true); //hardcoded base on html
        }

        var jsonEncodedModel = @Html.Raw(JsonConvert.SerializeObject(Model));
        ko.applyBindings(new TestViewModel(jsonEncodedModel));

</script>

然后你的模型属性 Id、Name 和 Address 将作为可观察对象在你的 TestViewModel 中创建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接