2014-01-15 19 views
0

我有以下HTML代码绑定的JSON调用的成员列表。这工作正常,但我现在想要找到一个基于MemberId的行并更改代码中的名称。如何查找代码中的行并使用KnockoutJS更改跨度值?

<ul data-bind="foreach: { data: members}"> 
    <li> 
     <span data-bind="text: $index"></span> 
     <span data-bind="text: $data.Name"></span> 
     <span data-bind="text: $data.MemberId"></span> 
    </li> 
</ul> 

<button id="btnChange">Change</button> 

<script> 
    $(function() { 
     $.getJSON("/home/memberlist", function(data) { 
      var viewModel = { 
       members: ko.observableArray(data), 
      }; 
      ko.applyBindings(viewModel); 
     }); 

     $('#btnChange').click(function() { 
      //I would like to find the row that is a match for a MemberId 
      // and change the name.... 
     }); 

    }); 
</script> 
+0

更强大(更清晰),如果你保存你的getJSON调用的结果在一个全局变量你可以在你的#btnChange监听器函数中引用它,并通过解析它作为json来访问MemberId,如果它正确的f ormatted,即proper_json = JSON.parse(data); proper_json.MemeberId等.. –

回答

2

如果希望数据更改反映在页面上,则必须使该数据可观察。这意味着将原始服务器数据映射到具有可观察属性的对象。

下面这段代码做到这一点:

// define a Member class 
function Member(data) { 
    this.MemberId = ko.observable(data.MemberId); 
    this.Name = ko.observable(data.Name); 
} 
Member.prototype.changeName = function() { 
    var newName = prompt("New name?", this.Name()); 
    if (newName) { 
     this.Name(newName); 
    } 
}; 

$(function() { 
    $.getJSON("/home/memberlist") 
    .then(function(rawData) { 
     return ko.utils.arrayMap(rawData, function (instanceData) { 
      return new Member(instanceData); 
     }); 
    }) 
    .done(function(mappedData) { 
     ko.applyBindings({ 
      members: observableArray(mappedData), 
      changeRandomName: function() { 
       var members = this.members(), 
        random = getRandomInt(0, members.length - 1); 

       members[random].changeName(); 
      } 
     }); 
    }); 
}); 

// courtesy of http://stackoverflow.com/a/1527820 
function getRandomInt(min, max) { 
    return Math.floor(Math.random() * (max - min + 1)) + min; 
} 

<ul data-bind="foreach: members"> 
    <li> 
     <span data-bind="text: $index"></span> 
     <span data-bind="text: Name"></span> 
     <span data-bind="text: MemberId"></span> 
    </li> 
</ul> 
<button data-bind="click: changeRandomName">Change</button> 

注...

  • 简单的foreach结合
  • 简单的text绑定(有是没有必要的在大多数情况下使用$data。它是隐含的。)
  • 使用click结合,而不是jQuery的事件处理程序(一件事你通常应该尝试在淘汰赛应用程序做的。做尽可能多,你可以淘汰赛。)
  • 使用jQuery的委托功能(then()done())改造和使用Ajax的结果 - 这是比使用成功回调模型
+0

好的,到达那里,但是我的世界中的按钮不在循环之中。 – Rippo

+0

你如何设想选择*哪个*项需要改变?(在你回答之前,如果你确实应该这样做 - 从用户体验的角度来看,作为用户,我直接想要点击我想改变的东西。) – Tomalak

+0

想想按钮点击上的乐透,成员列表我得到一个随机行,并将span标签更改为“Won”。它不是'CRUD或行选择'我在做别的你的答案将是现货。 – Rippo

0

你可以做这样的事情

<li id="$data.MemberID"> 
    ... 
</li> 

$('#btnChange').click(function() { 

    $("#memberID") 
    //Then get the second child and or set a class of name to the span and do 
    // $("#memberID > .name") 
    // to get the html node that you want 
}); 
+0

希望有一个淘汰赛的方式......双向绑定或我怀疑的东西 – Rippo

1

首先,由于您使用的淘汰赛,我想你应该按钮元素上使用的click binding handler。您编写的代码正是敲除尝试通过通用脚本部分(不作用域)通过id绑定事件。

@BenjaminDavid是对的。要查找html元素,您必须创建可搜索的内容(例如,行元素上的id属性)。再次,有一个淘汰赛binding handler to apply values to attributes

代码的id应用于行元素会是这样的:

<ul data-bind="foreach: { data: members}"> 
    <li data-bind="attr: {id: $data.MemberId}"> 
     <span data-bind="text: $index"></span> 
     <span data-bind="text: $data.Name"></span> 
     <span data-bind="text: $data.MemberId"></span> 
    </li> 
</ul> 

如果你想要的是改变一个成员的名字,那么你不应该使用HTML在所有的工作。您应该在“内存中”集合中找到该成员,并直接更改该值。数据将在UI中更新(如果该属性是可观察的)。

+0

是的,我明白了,点击绑定到viewmodel里面的一个功能,aha灯亮 – Rippo

+0

感谢您的支持+1 – Rippo

相关问题