2010-12-09 24 views
3

我和knockoutjs玩过一些小小的游戏,并且制作了下面的例子,足以让我兴奋的想法是在javascript中构建这些视图模型,以便视图可以用更简单,更容易声明的方式编写,即首先定义你想观察,然后用data-bind属性定义当你的viewmodel以某种方式改变时,你想要发生什么如何使用KnockoutJS通过AJAX观察服务器上的数据?

但是,所有这些只发生在客户端。

我该如何扩展此示例以使用knockoutjs来观察服务器上的对象的状态,例如,通过AJAX调用?

的index.htm:

<!doctype html> 
<html> 
    <title>Knockout example</title> 
    <head> 
     <script type="text/javascript" src="js/knockout-1.1.1.debug.js"></script> 
     <script type="text/javascript" src="js/main.js"></script> 
     <link rel="stylesheet" href="css/main.css" type="text/css"/> 
    </head> 
    <body> 

     <!-- FIRST AREA --> 
     <div class="infobox"> 
      <div data-bind="visible: noNamesFilled"> 
       <p>This is an example with NO names filled.</p> 
      </div> 
      <div data-bind="visible: bothNamesFilled"> 
       <p>This is an example with both names filled.</p> 
      </div> 
      <div data-bind="visible: firstNameOnlyFilled"> 
       <p>This is an example with only the first name filled.</p> 
      </div> 
      <div data-bind="visible: lastNameOnlyFilled"> 
       <p>This is an example with the last name filled but not the first name</p> 
      </div> 
     </div> 

     <!-- SECOND AREA --> 
     <p>First name: <input data-bind="value: firstName, valueUpdate:'afterkeydown'" /></p> 
     <p>Last name: <input data-bind="value: lastName, valueUpdate:'afterkeydown'" /></p> 
     <div data-bind="visible: bothNamesFilled"> 
      <h2 class="normal">Hello, <span data-bind="text: fullName"></span>.</h2> 
     </div> 
     <div data-bind="visible: firstNameOnlyFilled"> 
      <h2 class="informal">Hi there <span data-bind="text: fullName"></span>!</h2> 
     </div> 
     <div data-bind="visible: lastNameOnlyFilled"> 
      <h2 class="formal">Hello, Mr. <span data-bind="text: fullName"></span>.</h2> 
     </div> 

     <!-- THIRD AREA --> 
     <div data-bind="visible: noNamesFilled"> 
      <p><span class="bad">:-(</span> Please fill in both names.</p> 
     </div> 
     <div data-bind="visible: bothNamesFilled"> 
      <p><span class="good">:-)</span> Good job, both names are filled!</p> 
     </div> 
     <div data-bind="visible: firstNameOnlyFilled"> 
      <p><span class="ok">:-(</span> Please fill in the last name, too.</p> 
     </div> 
     <div data-bind="visible: lastNameOnlyFilled"> 
      <p><span class="ko">:-(</span> Please fill in the first name as well.</p> 
     </div> 
    </body> 
</html> 

的main.css:

* { margin: 0; padding: 0} 
body { margin: 10px} 
p { margin: 10px} 
.infobox { 
    background-color: #eee; 
    width: 300px; 
    height: 100px; 
    padding: 10px; 
} 
.informal { 
    color: purple; 
    font-family: arial; 
} 
.normal { 
    color: black; 
    font-family: new courier; 
} 
.formal { 
    color: black; 
    font-size: 11pt; 
    font-family: times roman; 
    background-color: #eee; 
} 
.good { 
    width: 20px; 
    background-color: lightgreen; 
} 
.ok { 
    width: 20px; 
    background-color: yellow; 
} 
.bad { 
    width: 20px; 
    background-color: tomato; 
} 

main.js:

window.onload= function() { 

    var viewModel = { 
     firstName : ko.observable(''), 
     lastName : ko.observable('') 
    }; 
    viewModel.fullName = ko.dependentObservable(function() { 
     return viewModel.firstName() + " " + viewModel.lastName(); 
    }); 

    viewModel.bothNamesFilled = ko.dependentObservable(function() { 
     return viewModel.firstName().length > 0 && viewModel.lastName().length > 0; 
    }, this); 
    viewModel.firstNameOnlyFilled = ko.dependentObservable(function() { 
     return viewModel.firstName().length > 0 && viewModel.lastName().length == 0; 
    }, this); 
    viewModel.lastNameOnlyFilled = ko.dependentObservable(function() { 
     return viewModel.firstName().length == 0 && viewModel.lastName().length > 0; 
    }, this); 
    viewModel.noNamesFilled = ko.dependentObservable(function() { 
     return viewModel.firstName().length == 0 && viewModel.lastName().length == 0; 
    }, this); 

    ko.applyBindings(viewModel); 
} 

回答

4

我将使用setTimeout来调用一个使用JQuery进行$ .ajax调用的函数。当它返回JSON数据时,将该数据设置为您的视图模型,最后再次设置setTimeout以调用该函数。

0

这是一个更新的示例,主要更新main.js以使用JQuery来执行ajax调用。

HTML文件包含Knockout 3而不是1.HTML还包含最新的JQuery,以使JQuery功能发挥作用。

js/server_data.js在那里,所以你有一些有效的json数据开始。您可以将$ .ajax设置中的url更改为您拥有的任何服务器端脚本,但尝试将其内容类型设置为application/json。例如,PHP脚本可以设置Content-type头,如:header('Content-type:application/json');然后以JSON格式打印出数据。

新main.html中:

<!doctype html> 
<html> 
    <title>Knockout example</title> 
    <head> 
     <script type="text/javascript" src="js/knockout-3.0.0.debug.js"></script> 
     <script src="http://code.jquery.com/jquery-latest.min.js"></script> 
     <script type="text/javascript" src="js/main.js"></script> 
     <link rel="stylesheet" href="css/main.css" type="text/css"/> 
    </head> 
    <body> 

     <!-- FIRST AREA --> 
     <div class="infobox"> 
      <div data-bind="visible: noNamesFilled"> 
       <p>This is an example with NO names filled.</p> 
      </div> 
      <div data-bind="visible: bothNamesFilled"> 
       <p>This is an example with both names filled.</p> 
      </div> 
      <div data-bind="visible: firstNameOnlyFilled"> 
       <p>This is an example with only the first name filled.</p> 
      </div> 
      <div data-bind="visible: lastNameOnlyFilled"> 
       <p>This is an example with the last name filled but not the first name</p> 
      </div> 
     </div> 

     <!-- SECOND AREA --> 
     <p>First name: <input data-bind="value: firstName, valueUpdate:'afterkeydown'" /></p> 
     <p>Last name: <input data-bind="value: lastName, valueUpdate:'afterkeydown'" /></p> 
     <div data-bind="visible: bothNamesFilled"> 
      <h2 class="normal">Hello, <span data-bind="text: fullName"></span>.</h2> 
     </div> 
     <div data-bind="visible: firstNameOnlyFilled"> 
      <h2 class="informal">Hi there <span data-bind="text: fullName"></span>!</h2> 
     </div> 
     <div data-bind="visible: lastNameOnlyFilled"> 
      <h2 class="formal">Hello, Mr. <span data-bind="text: fullName"></span>.</h2> 
     </div> 

     <!-- THIRD AREA --> 
     <div data-bind="visible: noNamesFilled"> 
      <p><span class="bad">:-(</span> Please fill in both names.</p> 
     </div> 
     <div data-bind="visible: bothNamesFilled"> 
      <p><span class="good">:-)</span> Good job, both names are filled!</p> 
     </div> 
     <div data-bind="visible: firstNameOnlyFilled"> 
      <p><span class="ok">:-(</span> Please fill in the last name, too.</p> 
     </div> 
     <div data-bind="visible: lastNameOnlyFilled"> 
      <p><span class="ko">:-(</span> Please fill in the first name as well.</p> 
     </div> 
    </body> 
</html> 

JS/main.js:

$(document).ready(function() { 

    var viewModel = { 
     firstName : ko.observable(''), 
     lastName : ko.observable('') 
    }; 
    viewModel.fullName = ko.dependentObservable(function() { 
     return viewModel.firstName() + " " + viewModel.lastName(); 
    }); 

    viewModel.bothNamesFilled = ko.dependentObservable(function() { 
     return viewModel.firstName().length > 0 && viewModel.lastName().length > 0; 
    }, this); 
    viewModel.firstNameOnlyFilled = ko.dependentObservable(function() { 
     return viewModel.firstName().length > 0 && viewModel.lastName().length == 0; 
    }, this); 
    viewModel.lastNameOnlyFilled = ko.dependentObservable(function() { 
     return viewModel.firstName().length == 0 && viewModel.lastName().length > 0; 
    }, this); 
    viewModel.noNamesFilled = ko.dependentObservable(function() { 
     return viewModel.firstName().length == 0 && viewModel.lastName().length == 0; 
    }, this); 

    ko.applyBindings(viewModel); 

    // send request to the server to download the server's model information. 
    $.ajax(
    { 
     'url': 'js/server_data.js', 
     'dataType': 'json', 
     'method': 'post', 
     'error': function(jqXHR, textStatus, errorThrown) 
     { 
      // error callback in case you play with this code and run into trouble. 
      alert('There was a problem handling the ajax request. The error information is: jqXHR: ' 
      +jqXHR+", textStatus: "+textStatus+", errorThrown: "+errorThrown); 
     }, 
     'success': function(data) 
     { 
      // when it is downloaded and parsed to create the "data" parameter, update the viewModel. 
      viewModel.firstName(data.firstName); 
      viewModel.lastName(data.lastName); 
     } 
    } 
    ); 
} 
); 

JS /表示动态生成数据server_data.js可能是从数据库:

{ 
    "firstName": "John", 
    "lastName": "Doe" 
} 

jsteve具有正确的概念,但不要使用setTimeout,如果你只是想在页面加载时下载数据秒。相反,使用JQuery的文档就绪回调函数和JQuery的ajax成功回调函数,以便在需要时能够正确运行。

如果要持续监听服务器中的数据更改并对其作出反应,请查看长轮询器技术。长轮询比效率更高,精确的定时比繁忙的等待要求对服务器提出频繁的新请求。

相关问题