繁体   English   中英

为什么这些AngularJS组件中的一个成功显示ng-model的值,而另一个不成功?

[英]Why does one of these AngularJS components successfully show the value of ng-model, while the other doesn't?

我正在尝试创建一系列可以导入到一个主要组件中的动态组件。 当我将所有对象传递到一个绑定而不是为每个传递的对象创建多个绑定时,将组件嵌入组件中要容易得多。 所以我创造了一个傻瓜来展示我想要实现的目标。 理想情况下,我希望能够将父组件中的对象传递到子组件的ng模型中,而无需创建单独的绑定。

这是否可能,有人可以给我任何建议或解释,为什么嵌套组件只在本地而不是在整个视图中更新模型?

基本上,如果你看下面的plunkr,我想让cNestedComponent以与cDirectComponent相同的方式运行,其中数据绑定从组件模板内部和模板外部更新。

http://plnkr.co/edit/vusx9rm1DnkbBlNBGyZG?p=preview

加价:

<h1> Data Comment => {{ data.comment }} </h1>
<c-direct-input plplaceholder="direct component" plmodel="data.comment" pltype="text"></c-direct-input>
<c-nested-input input-bindings="{type: 'text', model: 'data.comment', placeholder: 'nested component'}"></c-nested-input>

组件:

app.component('cNestedInput', {
  template: '\
    <h2> Nested Component </h2>\
    <p style="display: block;"> {{ $ctrl.inputBindings.model }} </p>\
    <input type="{{ $ctrl.inputBindings.type }}" placeholder="{{$ctrl.inputBindings.placeholder}}" ng-model="$ctrl.inputBindings.model" />\
  ',
  bindings: {
    inputBindings: '='
  },
  controller: function($scope) {}
});

app.component('cDirectInput', {
  template: '\
    <h2> Direct Component </h2>\
    <p style="display: block;"> {{ $ctrl.plmodel }} </p>\
    <input type="{{ $ctrl.pltype }}" placeholder="{{ $ctrl.plplaceholder }}" ng-model="$ctrl.plmodel" />\
  ',
  bindings: {
    plplaceholder: '@',
    plmodel: '=',
    pltype: '@'
  },
  controller: function($scope) {}
});

================================================== ======

UPDATE

根据用户Julien Tassin的反馈,我创建了一个更新的更新的plunker,我认为更好地展示了我的目标:

https://plnkr.co/edit/cvYAdB?p=preview

直接组件示例是实现我的目标的明确方法,但我宁愿不必列出每个单独的绑定,因为组件彼此嵌套。 例如:

<c-nested-input input-bindings="$ctrl.input.inputBindings"/>

键入然后输入这个更容易

<c-direct-input input-placeholder="{{$ctrl.inputPlaceholder}}" input-type="{{$ctrl.inputType}}" input-model="$ctrl.inputModel"/>\

每次我想将输入组件嵌套在父组件中。

希望此更新能够进一步澄清我正在寻找的内容。

有几个问题使您的示例无效:

第一个问题:不可转让的财产

您有“不可转让”的问题。 当您声明<c-nested-input input-bindings="{type: 'text', model: 'data.comment', placeholder: 'nested component'}"></c-nested-input> ,您创建了一个不可分配的属性{type: 'text', model: 'data.comment', placeholder: 'nested component'} (顺便说一句,你在'data.comment'上的错误应该是data.comment )。 当您尝试在ngModel中为其分配值时,它将失败,因为您不能影响不可赋值的表达式,甚至是不可赋值的表达式属性

因此,解决方案是在主控制器中设置可分配对象inputBindings并将其传递给组件。

第二期发布data.comment参考

那不是全部。 如果你试试 :

  $scope.data = {}
  $scope.inputBindings = {
    type: 'text',
    model: $scope.data.comment,
    placeholder: 'nested component'
  }

并将其传递给您的嵌套组件:

<c-nested-input input-bindings="inputBindings"></c-nested-input>

它不会按你的意愿工作。 因为当您的嵌套将修改inputBindings.model时,它将不是与data.comment相同的引用。 =绑定表示inputBindings而不是它的属性。

没有办法避免这种情况。

所以你必须放弃data.comment并按照以下方式工作:

MARKUP:

<body ng-controller="MainCtrl">
  <h1> Data Comment => {{ inputBindings.model }} </h1>
  <hr/>
  <c-direct-input plplaceholder="direct component" plmodel="inputBindings.model" pltype="text"></c-direct-input>
  <c-nested-input input-bindings="inputBindings"></c-nested-input>
</body>

JS:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.inputBindings = {
    type: 'text',
    placeholder: 'nested component'
  }
});

app.component('cNestedInput', {
  template: '\
    <h2> Nested Component </h2>\
    <p style="display: block;"> {{ $ctrl.data.comment }} </p>\
    <input type="{{ $ctrl.inputBindings.type }}" placeholder="{{ $ctrl.inputBindings.placeholder}}" ng-model="$ctrl.inputBindings.model" />\
  ',
  bindings: {
    inputBindings: '='
  },
  controller: function() {}
});

app.component('cDirectInput', {
  template: '\
    <h2> Direct Component </h2>\
    <p style="display: block;"> {{ $ctrl.plmodel }} </p>\
    <input type="{{ $ctrl.pltype }}" placeholder="{{ $ctrl.plplaceholder }}" ng-model="$ctrl.plmodel" />\
  ',
  bindings: {
    plplaceholder: '@',
    plmodel: '=',
    pltype: '@'
  },
  controller: function() {

  }
});

plunker中的例子

我的建议

我认为创建组件的更简洁方法是混合方法:

就像是 :

JS:

app.component('cHybridInput', {
  template: '\
    <h2> Nested Component </h2>\
    <p style="display: block;"> {{ $ctrl.data.comment }} </p>\
    <input type="{{ $ctrl.options.type }}" placeholder="{{ $ctrl.options.placeholder}}" ng-model="$ctrl.ngModel" />\
  ',
  bindings: {
    ngModel: '=',
    options: '<'
  },
  controller: function() {}
});

HTML:

<c-hybrid-input ng-model="inputBindings.model" options="inputBindings"></c-hybrid-input>

暂无
暂无

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

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