简体   繁体   English

Ember.js - 模型内部组件

[英]Ember.js - Model inside component

I am making an app just for practice and i have a doubt in a component's function "didReceiveAttr". 我正在制作一个仅用于练习的应用程序,我对组件的功能“didReceiveAttr”有疑问。 When i pass my MODEL in my template and then i erase some element in it the function doesnt work, but if i pass "model.length" in the template and then erase something the function work! 当我在我的模板中传递我的MODEL然后我擦除其中的一些元素时,该函数不起作用,但如果我在模板中传递“model.length”然后擦除某些功能工作!

My component template 我的组件模板

<h1>Tasks ({{totalTask}})</h1>

My component JS 我的组件JS

  totalTask: null,

  didReceiveAttrs(){
    this._super(...arguments);
    this.set('totalTask', this.get('model.length'));
    console.log(this.get('model'));
  }

My primary template 我的主要模板

{{task-list model=model}}

or 要么

{{task-list model=model.length}}

This is indeed the expected behavior; 这确实是预期的行为; just look at Ember guide about how didReceiveAttrs works. 只需看看Ember指南 ,了解didReceiveAttrs是如何工作的。 It is clearly stated that " didReceiveAttrs hook is called every time a component's attributes are updated". 明确指出“每次更新组件的属性时都会调用didReceiveAttrs钩子”。 When you add to or remove from an array the array itself does not change; 当您添加到数组或从数组中删除时,数组本身不会更改; hence didReceiveAttrs is not executed. 因此didReceiveAttrs没有被执行。 It is only executed when the initial assignment to model is performed. 它仅在执行model的初始分配时执行。

I prepared this twiddle to illustrate you a better ember way to handle this case. 我准备了这个旋风,以说明你处理这种情况的更好的余烬方式。 You should rely on computed properties as much as you can; 你应该尽可能多地依赖计算属性; hence I added computedTotalTask as a computed property to my-component.js and it relies on model.length as you can see. 因此,我将computedTotalTask作为计算属性添加到my-component.js ,它依赖于model.length如您所见。

{{task-list modelLength=model.length}}

Here you are assigning model.length as modelLength property to the component. 在这里,您将model.length指定为modelLength属性到组件。 so initially didReceiveAttrs will be called as component is receiving modelLength property and when you add one more element to model then modelLength property itself changed so this will invoke didReceiveAttrs before re-render. 所以最初didReceiveAttrs会组件接收被称为modelLength属性,当你添加更多的元素,然后模型modelLength属性本身更改,因此这将调用didReceiveAttrs前重新呈现。

{{task-list modelTaskList=model}}

Here modelTaskList is pointing to array, so when you add/remove item through KVO compliant method such as pushObject it will be reflected in component too. 这里modelTask​​List指向数组,所以当你通过KVO兼容方法(如pushObject)添加/删除项时,它也会反映在组件中。 but the modelTaskList is still pointing to the same array so didReceiveAttrs hook will not be called. 但是modelTask​​List仍然指向同一个数组,因此不会调用didReceiveAttrs钩子。 Suppose if you assigned different array then you can see the didReceiveAttrs is called. 假设您分配了不同的数组,那么您可以看到调用didReceiveAttrs。

You could always just set this as a computed property, ensuring updates in the event of the bound variable being updated. 您始终可以将其设置为计算属性,以确保在更新绑定变量时更新。

Within your component, set up a computed property that will watch for a change to your model, then update the variable modelLength with the change 在组件中,设置一个计算属性,该属性将监视模型的更改,然后使用更改更新变量modelLength

modelLength: Ember.computed('model', function(){
  return this.get('model').length;
}

Then, within your handlebars template, reference this length 然后,在您的车把模板中,引用此长度

<h1>Tasks{{#if modelLength}} ({{modelLength}}){{/if}}</h1>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM