React-Knockout无缝粘合,JavaScript项目MVVM框架下的控件化

前端之家收集整理的这篇文章主要介绍了React-Knockout无缝粘合,JavaScript项目MVVM框架下的控件化前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

这次讲的是把React和Knockout结合使用的示例,两个框架各有所长,也有不同的特点和特色,这次把他们结合起来,似乎有些胆大妄为,然而有时候就是容易遇到一些奇怪的需求。使得我们不得不去出一些奇招。然而这样真的很奇怪吗?实际上并不是这样子,使用react创建控件,再使用knockout构建MVVM框架,开发流程可以变得有条不絮,易于扩展维护,同时可实现代码重用,减少开发的工作量。

1.要构建React-Knockout MVVM框架我们首先需要下载React和knockout的JS库

React:http://facebook.github.io/react/

Knockout:http://knockoutjs.com/

2.下载完成后将react和knockout库文件导入到工程里,我在工程量建了framework文件夹来放置这些框架文件

3. 要使React和knockout融合,需要做一个特别的处理,在framework文件夹里新建一个knockoutReact.js文件,并向其添加如下代码

  1. var KnockoutMixin = {
  2.  
  3. updateKnockout:function() {
  4. this.__koTrigger(!this.__koTrigger());
  5. },componentDidMount:function() {
  6. this.__koTrigger = ko.observable(true);
  7. this.__koModel = ko.computed(function () {
  8. this.__koTrigger(); // subscribe to changes of this...
  9.  
  10. return {
  11. props: this.props,state: this.state
  12. };
  13. },this);
  14.  
  15. ko.applyBindings(this.__koModel,this.getDOMNode());
  16. },componentWillUnmount:function() {
  17. ko.cleanNode(this.getDOMNode());
  18. },componentDidUpdate:function() {
  19. this.updateKnockout();
  20. }
  21. };
  22.  
  23. var reactHandler = ko.bindingHandlers.react = {
  24. render: function ( el,Component,props ) {
  25. React.render(
  26. React.createElement(Component,props),el
  27. );
  28. },init: function ( el,valueAccessor,allBindingsAccessor,viewmodel,bindingContext ) {
  29. var options = valueAccessor();
  30. var Component = ko.unwrap(options.component || options.$);
  31. var props = ko.toJS(options.props || viewmodel);
  32.  
  33. reactHandler.render(el,props);
  34.  
  35. return { controlsDescendantBindings: true };
  36. },update: function ( el,props);
  37.  
  38. return { controlsDescendantBindings: true };
  39. }
  40. };

这片代码中第一段的作用是在react文件添加knockout绑定机制,第二段代码作用则是实现在UI中直接绑定UI元素来创建一个控件,例如使用<div data-bind="react: { $: CustomTextBox,props: $data }><div>就可以直接在html里创建一个CustomTextBox控件了

4. 下面我们来创建一个控件login,并将其放置在文件夹controls中,文件名称为login.jsx

  1. /**
  2. * data bind datas
  3. * 1. username 用户名
  4. * 2. password 密码
  5. * 3. loginCommand 登录事件
  6. */
  7.  
  8. var UserLogin = React.createClass({
  9. mixins: [ KnockoutMixin ],getDefaultProps:function(){
  10. return {
  11. labelUsername: "Username",labelPassword: "Password",};
  12. },render: function(){
  13. return <div style={{marginTop: 20,marginLeft: 20}}>
  14. <div>
  15. <label>{this.props.labelUsername}</label>
  16. <input type="text" style={{marginLeft: 20}}
  17. data-bind="value: props.username"/>
  18. </div>
  19. <div style={{marginTop: 10}}>
  20. <label>{this.props.labelPassword}</label>
  21. <input type="text" style={{marginLeft: 20}}
  22. data-bind="value: props.password"/>
  23. </div>
  24. <div style={{marginTop: 20,marginLeft: 150}}>
  25. <button data-bind="click: props.loginCommand"
  26. style={{width:100}}>Login</button>
  27. </div>
  28. </div>;
  29. },});

控件里用户名username,密码password,登录操作loginCommand是适应knockout data-bind绑定的,这个控件会被引用在某个view中然后绑定到viewmodel中,viewmodel的数据改变后,控件UI也会跟随改变,具体会是什么样子,请继续跟随下面的步骤。

5.在view文件夹里创建一个登录界面login.html。在这个页面里,使用了data-bind react:来创建我们上一个步骤的登录控件,并在后面的js代码中新建了一个viewmodel并将其绑定至UI中。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <Meta charset="UTF-8">
  5. <title id="title">Login</title>
  6.  
  7. <script type="text/javascript" src="../framework/react.js"></script>
  8. <script type="text/javascript" src="../framework/knockout-v3.3.0.js"></script>
  9. <script type="text/javascript" src="../framework/JSXTransformer.js"></script>
  10. <script type="text/javascript" src="../framework/knockoutReact.js"></script>
  11.  
  12. <script type="text/jsx" src="../controls/login.jsx"></script>
  13.  
  14. <script type="text/javascript" src="../viewmodel/loginviewmodel.js"></script>
  15. </head>
  16. <body style="background:lightblue">
  17. <div style="margin-left:30px">
  18. <button data-bind="click: viewmodel.fillInfo">Fill username and password</button>
  19. <button data-bind="click: viewmodel.clear">Clear</button>
  20. </div>
  21.  
  22. <div data-bind="react: { $: UserLogin,props: {
  23. username : username,password : password,loginCommand : viewmodel.startLogin.bind($data)
  24. }
  25. }">
  26. <div>
  27. </body>
  28.  
  29. <script type="text/jsx">
  30. var viewmodel = new loginviewmodel();
  31.  
  32. ko.applyBindings(loginviewmodel);
  33. </script>
  34.  
  35. </html>


绑定的元素有

username : username,控件的username绑定了View Model的username
password : password,控件的password绑定了View Model的password
loginCommand : viewmodel.startLogin.bind($data) 控件的loginCommand绑定了View Model的startLogin方法

6.新建一个viewmodel的文件夹并向其添加loginviewmodel.js,这是login view的viewmodel文件了,处理了login view里所需要的逻辑。

  1. var loginviewmodel = (function () {
  2. function loginviewmodel() {
  3. this.username = ko.observable();
  4. this.password = ko.observable();
  5. }
  6.  
  7. /**
  8. * 登录操作
  9. */
  10. loginviewmodel.prototype.startLogin = function () {
  11. var name = this.username();
  12. var secure = this.password();
  13.  
  14. alert("Username: " + name + "\nPassword: " + secure);
  15. }
  16.  
  17. /**
  18. * 填充用户名和密码
  19. */
  20. loginviewmodel.prototype.fillInfo = function () {
  21. this.username("YLD");
  22. this.password("123");
  23. }
  24.  
  25. /**
  26. * 清空用户名和密码
  27. */
  28. loginviewmodel.prototype.clear = function () {
  29. this.username("");
  30. this.password("");
  31. }
  32.  
  33. return loginviewmodel;
  34. })();


7.工程创建实现完成,现在运行下吧。我这里使用的是google chrome浏览器,然后要此工程在浏览器里运作成功,还必须做一个特别的处理。右击chrome浏览器快捷方式,打开属性。在目标后面添加--disable-web-security

工程运行效果如下

代码下载地址:http://download.csdn.net/detail/leyyang/9022673

猜你在找的React相关文章