【问题标题】:How do i create a fully dynamic databinding in javascript如何在 javascript 中创建完全动态的数据绑定
【发布时间】:2017-10-04 13:14:22
【问题描述】:

我的目标是实现类似于 .NETs BindingList 的东西。首先我认为从 'BindingObject' 开始会更简单。

每当我的对象的属性更改/创建/删除时,我都想抛出一个事件或调用一个函数。最后,我希望能够动态地对对象的每个属性做出反应。

我已经阅读了几篇关于如何解决此问题的文章。使用 JavaScript 代理的大多数建议。

这是我现在尝试的:

var handler = {
    get: function (target, propname) {
        console.log('get');
        return target[propname];
    }};

BindingObject.prototype.constructor = new Proxy({}, handler);

function BindingObject(object) {
    //access handler here
}

当然,我希望为每个创建的对象创建一个处理程序,而不是为每个对象创建一个相同的处理程序。我也很想在我也无法工作的构造函数中传递代理对象和处理程序。

这是我的第二次尝试,它允许在构造函数中传递我的对象,但我无法访问我的处理程序:

class BindingObject2 {
    constructor(obj) {
        this.handler = {
            get: function (target, propname) {
                console.log('get');
                return target[propname];
            }};
        return new Proxy(obj || {}, this.handler);
    }
}

【问题讨论】:

    标签: javascript data-binding proxy handler


    【解决方案1】:

    基于类的方法不能满足 OP 的所有要求。提供的示例代码已经很明显了。有一个构造函数创建一个具有handler 属性的类型但不返回它,而是构造函数返回一个代理对象。

    一个好的旧工厂函数可能是更好的选择......

    function createComposedProxyType(trapHandlerOptions, type) {
      var proxy = new Proxy((type || {}), trapHandlerOptions);
      proxy.__traps__ = trapHandlerOptions;
      return proxy;
    }
    
    function handlePropertyChange(target, key, value/*, receiver*/) {
      console.log("handlePropertyChange :: [key, value] :", key, value);
      target[key] = value;
      return true;
    }
    
    var trapConfig = {
      set: handlePropertyChange
    };
    
    var type = createComposedProxyType(trapConfig);
    
    console.log('type : ', type);
    
    type.foo = 'foo';
    type.bar = 'bar';
    
    console.log('type : ', type);
    .as-console-wrapper { max-height: 100%!important; top: 0; }

    【讨论】:

    • 还没试过,但目前看起来不错。非常喜欢!
    【解决方案2】:

    在 JS 中只使用数据绑定会有问题。它可能是流行框架的一部分:angular、aurelia 或 react(有点……+redux 即将死亡)。

    使用 jQuery,它需要手动连接所有的 prop 更改。可能实现一些观察者/订阅者方法。

    或者使用一些提供足够方便的数据绑定定义命令的数据绑定任务的组件。我用databindjs做到了。例如

    // Lets assume that there is just simple form (target)
    var simpleForm = {
       input: $('.simple .input-value'),
       output: $('.simple .output-value')
    };
    // And here is the simple model object (source)
    var model = {
        text: 'initial value'
    };
    
    // Lets set two directional binding between [input] <-> [text]
    var simpleBinding = bindTo(simpleForm, () => model, {
        'input.val': 'text',  // bind to user input
        'output.text': 'text'  // simple region that will react on user input
    });
    // This command will sync values from source to target (from model to view)
    updateLayout(simpleBinding);
    subscribeToChange(simpleBinding, () => {
        $('.simple .console').html(JSON.stringify(model));
    });
    // Just initialize console from default model state
    $('.simple .console').html(JSON.stringify(model));
    

    完整解决方案here。 可以查看数据绑定核心的完整实现on github

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多