Javascript 如何使用ES6记录聚合物行为?

Javascript 如何使用ES6记录聚合物行为?,javascript,polymer,web-component,Javascript,Polymer,Web Component,如果我这样做 Polymer({ is: 'pp-app', behaviors: [PlayPlan.HelperBehavior], scrollPageToTop() { document.getElementById('mainContainer').scrollTop = 0; }, onDataRouteClick() { var drawerPanel = document.querySelector('#paper

如果我这样做

Polymer({
    is: 'pp-app',
    behaviors: [PlayPlan.HelperBehavior],
    scrollPageToTop() {
      document.getElementById('mainContainer').scrollTop = 0;
    },

    onDataRouteClick() {
      var drawerPanel = document.querySelector('#paperDrawerPanel');
      if (drawerPanel.narrow) {
        drawerPanel.closeDrawer();
      }
    }
  });
这里的行为可以正常工作,但在es6中

  class PlayPlanApp {
    beforeRegister() {
      this.is = 'pp-app';
      this.properties = {};
      this.behaviors = [PlayPlan.HelperBehavior];
    }

    scrollPageToTop() {
      document.getElementById('mainContainer').scrollTop = 0;
    }

    onDataRouteClick() {
      var drawerPanel = document.querySelector('#paperDrawerPanel');
      if (drawerPanel.narrow) {
        drawerPanel.closeDrawer();
      }
    }
  }
  Polymer(PlayPlanApp);
行为将不起作用,如何在使用es6时指定行为?

这是由于

registerCallback: function() {
      // TODO(sjmiles): perhaps this method should be called from polymer-bootstrap?
      this._desugarBehaviors(); // abstract
      this._doBehavior('beforeRegister'); // abstract
      this._registerFeatures();  // abstract
      this._doBehavior('registered'); // abstract
    }
\u doBehavior('beforegister')
\u desugarbehavior
之后,这里有一个解决方法:

get behaviors() {
      return [PlayPlan.HelperBehavior];
    }
顺便说一句,这将不起作用,因为构造函数从未被调用(在Polymer.Base中注释)


请注意,如果使用扩展行为,wener给出的答案将不起作用。聚合物中的扩展行为是行为本身的阵列。我不知道到底发生了什么,但显然Polymer正在解析类的原型并将行为数组展平,将展平的版本写回原型。fixed getter函数将忽略展平版本并始终返回深数组。那不行。所以你有两个选择。 您可以自己展平阵列:

get behaviors() {
    return [
        MyFlatBehavior, MyExtendedBehavior
    ].reduce(function(a, b) {return a.concat(b);});
}
然而,由于Polymer可能会大量调用get行为(在我的例子中是这样的),这将引入一个较小的性能损失。另一种选择是让它设置行为:

let SkeletonPolymerBehavior = [MyFlatBehavior, MyExtendedBehavior];
class SkeletonPolymer {
    get behaviors( ) {return SkeletonPolymerBehavior;}
    set behaviors(b) {SkeletonPolymerBehavior = b;}
    ...
}
function addBehaviors(clas, ...behaviors) {
    let bhv = behaviors;
    Object.defineProperty(clas.prototype, "behaviors", {
        get:function( ) {return bhv;},
        set:function(b) {return bhv = b;}
    });
}
最后,您可以立即展平阵列:

let SkeletonPolymerBehavior = [
    MyFlatBehavior, MyExtendedBehavior
].reduce(function(a, b) {return a.concat(b);});
class SkeletonPolymer {
    get behaviors( ) {return SkeletonPolymerBehavior;}
    ...
}
请注意,我的展平功能不安全!在我的案例中,它是有效的,但在扩展扩展行为时,它将失败,在其他情况下也可能失败。你肯定需要更复杂的东西。如果你不想麻烦(而且我看不出有什么令人信服的理由),你肯定应该使用第二个版本,让聚合物来设定行为

最后一点:我尝试将其抽象为一个es2015行为混合器。然而,Polymer的原型魔法并没有捕获从基类继承的东西,并且从未调用在基类中定义的getter和setter

然而,有可能以es5的方式弄乱原型。此实用程序功能将简化扩展行为的添加:

let SkeletonPolymerBehavior = [MyFlatBehavior, MyExtendedBehavior];
class SkeletonPolymer {
    get behaviors( ) {return SkeletonPolymerBehavior;}
    set behaviors(b) {SkeletonPolymerBehavior = b;}
    ...
}
function addBehaviors(clas, ...behaviors) {
    let bhv = behaviors;
    Object.defineProperty(clas.prototype, "behaviors", {
        get:function( ) {return bhv;},
        set:function(b) {return bhv = b;}
    });
}
用法:

class SkeletonPolymer {...}
addBehaviors(SkeletonPolymer, MyFlatBehavior, MyExtendedBehavior);