Angular UI 模态 2 方式绑定不起作用
Posted
技术标签:
【中文标题】Angular UI 模态 2 方式绑定不起作用【英文标题】:Angular UI Modal 2 Way Binding Not Working 【发布时间】:2014-06-24 11:47:46 【问题描述】:我正在添加一个 Angular UI 模态,我将范围传递到模态窗口以进行 2 路绑定。我使用resolve
方法来传递范围值。这样做有点工作意思,当 ng-model 值在父项中发生变化时,它会反映在模态窗口内。但是,如果值在模态窗口内发生变化,它不会反映在父 ng-model 中。这是我的代码:
HTML:
<div ng-app="app">
<div ng-controller="ParentController">
<br />
<input type="text" ng-model="textbox.sample" />
<a class="btn btn-default" ng-click="open(textbox.sample)">Click Me</a>
<script type="text/ng-template" id="ModalContent.html">
<input type = "text" ng-model= "ngModel" / >
</script>
<br /> textbox
</div>
</div>
控制器:
var app = angular.module('app', ['ui.bootstrap']);
app.controller('ParentController', function ($scope, $modal)
$scope.textbox = ;
// MODAL WINDOW
$scope.open = function (_ngModel) // The ngModel is passed from open() function in template
var modalInstance = $modal.open(
templateUrl: 'ModalContent.html',
controller: ModalInstanceCtrl,
resolve:
ngModel: function ()
return _ngModel;
// end resolve
);
;
);
var ModalInstanceCtrl = function ($scope, $modalInstance, ngModel)
$scope.ngModel = ngModel;
;
为什么在上面的代码中父实例和模态实例之间的 2 路绑定不起作用?
【问题讨论】:
您实际上希望看到双向绑定发生在哪里,您在哪里打印出textbox
?如果是这种情况,一旦您进入模态,您将不再对 $scope.textbox
采取行动,当您将其传递为 _ngModel
时,您将创建 $scope.textbox
的副本,然后您的模态 $scope
项目是$scope.ngModel
... 尝试在父级上打印 ngModel
看看会发生什么
在modals open函数中最好将$scope作为option参数传递
@Tom 当我说 2 路绑定时,我的意思是如果这些值中的任何一个发生变化,我希望父窗口和模式窗口中的文本框输入发生变化。例如,在我的示例中,父级中 input
的 ng-model 和模态窗口中的 input
是相同的。因此,当我在父 input
中键入内容然后打开模态时,我可以看到模态 input
具有相同的值。但是当我在模态实例的input
中键入内容时,它不会在父输入中更新它。当这两个被同一个 ng-model 绑定时,它不应该更新吗?
@blackops_programmer,它们不一样ng-model="ngModel"
和ng-model="textbox.sample"
不同,因此不会互相更新。它从父模式到模态的原因是因为您每次打开模态窗口时都在设置它。
aha.. 所以如果我希望父 ng-model 反映模态实例内部所做的任何更改,我该怎么做?在这种情况下,在父控制器中放置 $watch
会起作用吗?如果是这样,我该如何添加?
【参考方案1】:
对我来说,以上都不起作用。
相反,我必须像 this comment in github 中建议的那样做。
要绑定的变量必须是一个对象,而不仅仅是一个简单的值。
例如,如果$scope.value
不起作用,则使用$scope.someObject.value
将起作用。
【讨论】:
【参考方案2】:我认为您的印象是父级中的ng-model="textbox.sample"
和模态中的ng-model="ngModel"
是相同的,因为您将textbox.sample
传递给模态并且您能够在模态窗口。这样做的唯一原因是您每次打开模态窗口时都明确设置 $scope.ngModel
属性。
使这项工作按预期工作的一种方法是在两个地方都使用$scope.textbox.sample
属性,但我不建议这样做。
也许正确的方法是使用modalInstance.result
承诺,如下所示:
在模态框上创建一个按钮并将其设为ng-click="ok()"
$scope.ok = function ()
$modalInstance.close($scope.ngModal); // will return this to the modalInstance.result
然后在父控制器中,或者任何打开模态窗口的地方:
$scope.open = function (_ngModel) // The ngModel is passed from open() function in template
var modalInstance = $modal.open(
templateUrl: 'ModalContent.html',
controller: ModalInstanceCtrl,
resolve:
ngModel: function ()
return _ngModel;
// end resolve
);
modalInstance.result.then(function (result)
$scope.textbox.sample = result;
);
;
【讨论】:
你说的很对。我完全误解了,因为我认为通过 open() 传递 ng-model 将为模态提供相同的 ng-model 范围并自动绑定两个模型。你的回答让我明白了这一点。我喜欢您使用modalInstance.result
承诺更新父级的 ng-model 并将其与模态实例同步的建议。完全有道理!我会在我的代码上试一试,然后报告。
对不起,我又回来了。在我的代码中,我现在通过 $modalInstance.close
传递更新的 ng-model。但是,我在处理承诺的父控制器中添加最后一个代码时遇到了一些麻烦。当我添加该代码时,我收到modalInstance is not defined
错误。我想我将此代码放在父控制器内的错误位置。这是在$scope.open
函数内部还是外部?我还需要在父控制器中添加$modalInstance
DI 吗?对不起,如果这是一个愚蠢的问题。
是的,您需要在定义modalInstance
的同一块中执行modalInstance.result
,即var modalInstance = $modal.open(...); modalInstance.result.then(...)
非常感谢!这真的很有帮助,我喜欢使用结果承诺的想法。
我们可以为此买一个 Plunker。【参考方案3】:
变化:
<input type = "text" ng-model= "ngModel" / >
进入:
<input type = "text" ng-model= "$parent.ngModel" / >
这与嵌入有关。检查:https://github.com/angular-ui/bootstrap/issues/969
【讨论】:
谢谢!很高兴我做到了! :)以上是关于Angular UI 模态 2 方式绑定不起作用的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 2 中,当我尝试使用两种方式绑定时,ngIF 不起作用
Angular Bootstrap 模态弹出自动对焦不起作用
使用 ngModel 的 Angular 2 双向绑定不起作用