Javascript 为什么这些AngularJS组件中的一个成功地显示了ng模型的价值,而另一个没有';T

Javascript 为什么这些AngularJS组件中的一个成功地显示了ng模型的价值,而另一个没有';T,javascript,angularjs,angular-ngmodel,angular-components,Javascript,Angularjs,Angular Ngmodel,Angular Components,我正在尝试创建一系列可以导入到一个主组件中的动态组件。当我可以将所有对象传递到一个绑定中时,将组件嵌套在组件中要容易得多,而不是为传递的每个对象创建多个绑定。所以我创建了一个plunkr来展示我想要实现的目标。理想情况下,我希望能够将对象从父组件传递到子组件的ng模型,而不必创建单独的绑定 这是否可能,有人能给我一些建议或解释,说明为什么嵌套组件只在本地更新模型,而不是在整个视图中更新模型 基本上,如果您查看下面的plunkr,我想让cNestedComponent以与cDirectCompon

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

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

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

标记:

<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>
Data Comment=>{{Data.Comment}
组成部分:

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) {}
});
app.component('cNestedInput'{
模板:'\
嵌套组件\

{{$ctrl.inputBindings.model}

\ \ ', 绑定:{ 输入绑定:'=' }, 控制器:函数($scope){} }); 应用组件('cDirectInput'{ 模板:'\ 直接分量\

{{$ctrl.plmodel}}

\ \ ', 绑定:{ PLP占位符:“@”, plmodel:“=”, pltype:“@” }, 控制器:函数($scope){} });
=================================================================================

更新

根据用户Julien Tassin的反馈,我创建了一个更新的plunker,它既更干净,也更好地展示了我的目标:

直接组件示例是实现我的目标的一种明确方式,但我不希望在组件相互嵌套时列出每个绑定。例如:

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

打印出来比打印出来容易多了

<c-direct-input input-placeholder="{{$ctrl.inputPlaceholder}}" input-type="{{$ctrl.inputType}}" input-model="$ctrl.inputModel"/>\
\
每次我想将输入组件嵌套在父组件中时


希望这次更新能进一步澄清我在寻找什么

有几个问题使您的示例不起作用:

第一个问题:不可转让财产 你有一个“不可转让”的问题。声明
时,您创建了一个不可分配的
{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>
JS:

var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数($scope){
$scope.inputBindings={
键入:“文本”,
占位符:“嵌套组件”
}
});
应用组件('cNestedInput'{
模板:'\
嵌套组件\

{{$ctrl.data.comment}}

\ \ ', 绑定:{ 输入绑定:'=' }, 控制器:函数(){} }); 应用组件('cDirectInput'{ 模板:'\ 直接分量\

{{$ctrl.plmodel}}

\ \ ', 绑定:{ PLP占位符:“@”, plmodel:“=”, pltype:“@” }, 控制器:函数(){ } });
中的示例

我的建议 我认为创建组件的更干净的方法是混合方法:

比如:

JS:

app.component('cHybridInput'{
模板:'\
嵌套组件\

{{$ctrl.data.comment}}

\ \ ', 绑定:{ ngModel:“=”,
选项:谢谢你非常详细的回复!我肯定会尝试一下,但这并不是我所希望的。有什么方法可以让我“转换”吗将inputBindings.model从cNestedInput组件中转换为可分配属性?此外,我尝试删除data.comment周围的引号,但随后输入锁定,我收到一个控制台错误:(创建组件的最“angularish”方法是为模型创建一个类似的绑定(您应该明确命名为ngModel)另一个是选项。我明天会用这个建议更新答案。非常感谢!我确实想指出,我确实对原始帖子进行了一些更新。我还想提到一个事实,即当您从data.comment中删除引号并更改直接输入中的文本时,它会更新n中的模型绑定ested输入(但是您仍然无法在文本字段中键入)。相反,如果在“data.comment”周围添加引号,则可以在文本字段中键入,但模型绑定仅在本地更新。如果没有引号,则会出现“不可分配属性”问题
<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>
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() {

  }
});
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() {}
});
<c-hybrid-input ng-model="inputBindings.model" options="inputBindings"></c-hybrid-input>