是否可以通过模板将父组件的属性绑定到子组件计算属性?
目标是通过绑定访问子组件的计算属性。
// We are in some parent component's template
{{child-component aComputedProp=aNonComputedProp}}
// Parent component
export default Ember.Component.extend({
aNonComputedProp: null
});
// Child component
export default Ember.Component.extend({
aComputedProp: function () {
return 4 + 4;
}.property()
});
更新
@KalmanKalman Hazins
虽然这种方法在对该子组件执行操作时效果很好,但当祖先组件需要访问该子组件的数据时,该方法将无效。
这是描述困境的图像。
我能想到让组件彼此通信而没有硬依赖性的唯一方法是通过服务(或充当服务的父组件),以及伪装的API的一系列触发器/处理程序事件
更新
我想的另一种方法是通过以下方式从ChildComponent1装饰父控制器:
decorateTargetObject: function () {
Ember.defineProperty(this.get('targetObject'), 'height', Ember.computed(function () {
return this.$().outerHeight();
}.bind(this)));
}.on('init')
ChildComponent2可以通过this.get('targetObject.height')
当然,这会破坏单向封装,因为组件需要浸入其控制器中。
没有办法将现有属性设置为计算属性而不重新定义它(没有Ember.defineProperty
)?
//In ChildComponent1
decorateTargetObject: function () {
this.set('targetObject.height', ...a computed function...)
}.on('init')
答案 0 :(得分:0)
这是不可能的(直接通过模板),但这就是你要做的:)(而不是)。
您可以向父级发送操作,并将值传递给更改。然后,在父操作中,您可以更新值。
App.XParentComponent = Ember.Component.extend({
helloParent: null,
actions: {
updateHelloParent: function(value){
this.set('helloParent', value);
}
}
});
App.XChildComponent = Ember.Component.extend({
helloName: function(){
var name = this.get('name');
var helloName = '';
if(name) {
var helloName = "Hello " + name;
}
this.sendAction('action', helloName);
return helloName;
}.property('name')
});
您的模板如下所示:
<script type="text/x-handlebars" id="components/x-parent">
<h2>Parent</h2>
{{ helloParent }}
{{ x-child action="updateHelloParent"}}
</script>
<script type="text/x-handlebars" id="components/x-child">
<h2>Child</h2>
{{ input value=name }} <p/>
{{ helloName }}
</script>
工作解决方案here
<强>更新强>
根据docs,您可以针对您的用例执行以下操作:
App.HeightController = Ember.Controller.extend({
height: 0
});
App.IndexController = Ember.Controller.extend({
needs: ['height'],
height: Ember.computed.alias('controllers.height.height')
});
App.XChild1Component = Ember.Component.extend({
heightDidChange: function(){
var val = this.get('val');
if(val) {
this.set('height', parseInt(val));
}
}.observes('val')
});
然后,在您的模板中,您可以拥有以下内容:
<script type="text/x-handlebars" data-template-name="index">
Height(index): {{ height }} <p/>
{{ x-parent height=height}}
</script>
<script type="text/x-handlebars" id="components/x-parent">
<h2>Parent</h2>
Height(parent): {{ height }} <p/>
{{ x-child1 height=height}}
{{ x-child2 height=height}}
</script>
<script type="text/x-handlebars" id="components/x-child1">
<h2>Child 1</h2>
Height(child1): {{ height }} <p/>
{{ input value=val placeholder='Type new heght here...'}} <p/>
</script>
<script type="text/x-handlebars" id="components/x-child2">
<h2>Child 2</h2>
Height(child2): {{ height }} <p/>
</script>
更新了解决方案here