组件共享变量由于某种原因

时间:2014-12-29 21:49:54

标签: ember.js

我对我创建的包装组件有一些奇怪的行为。

  1. 当我改变路线时,steps[]似乎一直存在,所以如果我在两条路线之间往返,我的步骤阵列就不会重新初始化并变得越来越大因此我需要手动重新初始化它:

    setup : function() {
        this.set('steps', []);
    }.on('init'),
    
  2. 为什么我需要这样做?我认为当你再次访问这条路线时,组件会重新生成。

    1. 另一个非常奇怪的行为是,如果我在同一页面上有两个这样的组件并且不使用上面的setup函数,那么它们将共享相同的steps[]。这是怎么回事,因为组件完全相互分离?这几乎就像step[]是全局变量之类的东西。
    2. 向导for.js

      export default Ember.Component.extend({
          tagName:'div',
          attributeBindings:['role', 'model', 'guided'],
          role : 'tabpanel',
          model : null,
          tab:'tab',
      
          steps : [],
      
          guided : true,
          notGuided : Ember.computed.not('guided'),
      
          setup : function() {
              this.set('steps', []);
          }.on('init'),
      
          showNext : function() {
              this.$('.nav-tabs > .active').next('li').find('a').tab('show') ;
          },
      
          showPrevious : function() {
              this.$('.nav-tabs > .active').prev('li').find('a').tab('show') ;
          },
      
          actions : {
              tabClicked : function() {
                  return false;
              }
          }
      
      });
      

      向导for.hbs

      <!-- Nav tabs -->
      <ul class="nav nav-tabs" role="tablist">
          {{#each step in steps}}
              <li role="presentation" {{bind-attr class="step.isActive:active guided:disabled"}}>
                  {{#if guided}}
                      <a aria-controls="{{unbound step.elementId}}">{{step.title}}</a>
                  {{else}}
                      <a aria-controls="{{unbound step.elementId}}" href="{{unbound step.tabLink}}" data-toggle="tab" role="tab">{{step.title}}</a>
                  {{/if}}
              </li>
          {{/each}}
      </ul>
      
      <!-- Tab panes -->
      <div class="tab-content">
          {{yield}}
      </div>
      

      向导step.js

      export default Ember.Component.extend({
          tagName:'div',
          attributeBindings:['role', 'title'],
          classNames : ['tab-pane'],
          classNameBindings : ['isActive:active'],
          isActive : false,
          role : 'tabpanel',
          title : '...',
      
          guided : Ember.computed.alias('parentView.guided'),
          notGuided : Ember.computed.alias('parentView.notGuided'),
      
          tabLink : function() {
              return '#' + this.get('elementId');
          }.property(),
      
          setup : function() {
            var steps = this.get('parentView.steps');
            steps.pushObject(this);
          }.on('init'),
      
          model : Ember.computed.alias('parentView.model'),
      
          actions : {
              next : function() {
                  var parent = this.get('parentView');
                  parent.showNext();
              },
      
              previous : function() {
                  var parent = this.get('parentView');
                  parent.showPrevious();
              }
          }
      
      });
      

      向导step.hbs

      {{yield}}
      
      {{#if guided}}
          <div>
              <button type="button" class="pull-right btn btn-primary" {{action "next"}}>Next</button>
              <button type="button" class="pull-left btn btn-default" {{action "previous"}}>Previous</button>
          </div>
      {{/if}}
      

      使用示例

      {{#wizard-for model=model2 guided=true}}
          {{#wizard-step isActive=true title='Step 1'}}
              hello
          {{/wizard-step}}
      
          {{#wizard-step title='Step 2'}}
          world
          {{/wizard-step}}
      {{/wizard-for}}
      
      
      <h3>Wizard - Not Guided</h3>
      {{#wizard-for model=model3 guided=false}}
          {{#wizard-step isActive=true title='Step 3'}}
              hello
          {{/wizard-step}}
      
          {{#wizard-step title='Step 4'}}
              world
          {{/wizard-step}}
      {{/wizard-for}}
      

1 个答案:

答案 0 :(得分:5)

我非常确定,因为您在组件定义中定义了steps : [],。由于数组是JavaScript中的对象,因此您基本上为所有组件提供对同一对象的引用,因此它将在组件类的所有实例之间共享。在标准OOP中,您要创建一个基本上是全局的类变量。

要解决此问题,请更改steps : [], - &gt; steps: null,然后创建一个init方法,初始化实例的steps属性:

initSteps: function() {
    this.set('steps', Ember.A());
}.on('init')