有没有办法动态添加行为?

时间:2016-12-16 03:43:49

标签: polymer polymer-1.0

我想在已加载组件/行为之后添加行为,或者在其组件中添加behevaior的某个函数。

这样的事情:

<script>
// samplebehavior.html file
// this is the behavior file
samplebehavior = {
   testAlert: function(){
       alert('test');
   }
};
</script>

// my-component.html
<script>
Polymer({
   is: "my-component",
   test: function() {
        url = "samplebehavior.html";
        var importHTML = new Promise(function(resolve, reject) {
                            Polymer.Base.importHref(url, function(e) {
                                resolve(e.target);
                            }, reject);
                        });

        importHTML.then(function(element) {
           // add a behavior here
           // I know this script does not work
           this.push('behaviors', samplebehavior);
        });

   }
});
</script>

这样我就可以访问testAlert()函数。

如何动态添加行为?

3 个答案:

答案 0 :(得分:0)

据我所知,这是不可能的。

构建原型时,行为与元素定义混合在一起。

您可以做的是动态生成行为数组

var behavior = {
  properties: {
    smth: {
      value: 'initial value'
    }
  }
}

Polymer({
  is: 'my-elem',
  behaviors: getBehaviors()
});

function getBehaviors() {
  return [ behavior ];
}

请记住,getBehaviors只会被调用一次。之后,您将无法改变元素的行为。

答案 1 :(得分:0)

这很丑陋,但您可以在对象中复制行为的所有成员

<script>
// samplebehavior.html file
// this is the behavior file
samplebehavior = {
   testAlert: function(){
       alert('test');
   }
};
</script>

// my-component.html
<script>
Polymer({
   is: "my-component",
   test: function() {
        url = "samplebehavior.html";
        var importHTML = new Promise(function(resolve, reject) {
                            Polymer.Base.importHref(url, function(e) {
                                resolve(e.target);
                            }, reject);
                        });

        importHTML.then(function(element) {
            for (let member in samplebehavior) {
                this[member] = samplebehavior[member];
            }
        });

   }
});
</script>

或许您可以调用内部方法_prepBehavior() https://github.com/Polymer/polymer/blob/ff6e884ef4f309d41491333860a8bc9c2f178696/src/micro/behaviors.html#L111

但我不知道这是否可以起到副作用

<script>
// samplebehavior.html file
// this is the behavior file
samplebehavior = {
   testAlert: function(){
       alert('test');
   }
};
</script>

// my-component.html
<script>
Polymer({
   is: "my-component",
   test: function() {
        url = "samplebehavior.html";
        var importHTML = new Promise(function(resolve, reject) {
                            Polymer.Base.importHref(url, function(e) {
                                resolve(e.target);
                            }, reject);
                        });

        importHTML.then(function(element) {
           this.push('behaviors', samplebehavior);
           this._prepBehaviors();
        });

   }
});
</script>

答案 2 :(得分:0)

通过引入lazyRegister设置的新值,这已成为部分的可能。

通过部分,我的意思是,如果您可以编辑要添加行为的元素的代码,则只能执行此操作。

动态添加行为需要进行三项更改

  • lazyRegister设置为max

    window.Polymer = {
       lazyRegister:"max"
    };
    
  • 就像@tomasz建议的那样,要在元素中动态添加行为使用函数添加行为。就是这样,因为我们将无法访问我们将尝试动态添加新行为的元素(至少我无法)。

    Polymer({
      .
      .
      behaviors: getBehavior(),
      .
      .
    });
    function getBehavior(){
      var myArr = [myBehavior];
      document.addEventListener('add-behavior',function(e){
        debugger;
        myArr.push(e.detail);
      });
      return myArr;
    }
    
  • 从要动态添加行为的元素中使用beforeRegister回调来调度添加新行为对象的事件

     beforeRegister: function(){
        var event = new CustomEvent('add-behavior',{
             detail:{
                func: function(){console.log(this.myProp,"!")}
             }
        });
        document.dispatchEvent(event);
    }
    

Here's作为工作范例的傻瓜。