为什么我的$ scope变量只在HTML中而不是在AngularJS中使用Bootstrap时在控制器中更新?

时间:2014-02-11 22:34:18

标签: angularjs angular-ui-bootstrap

我正在使用Angular的UI Bootstrap来显示模态叠加,用户可以在选择框中选择一个项目。用户选择的值应该在覆盖图的控制器中可用,以发送回打开控制器。在模态的HTML中,这可以工作:

<select
     ng-model="selectedItem"
     ng-options="item for item in items">
</select>
Selected: <b>{{ selectedItem }}</b>

但在控制器中,这始终是未定义的:

$scope.selectedItem;

为什么我无法在控制器中访问此值?

我正在开发的项目还有一些移动部件(我使用的是typeahead和buttons指令而不是简单的选择)但我将这个问题简化为这个工作示例:http://plnkr.co/edit/lb0NAGLR8eEVrywA67EC?p=preview。在此示例中,当模态关闭时,模态中的选择应显示在父页面上。

3 个答案:

答案 0 :(得分:2)

使用AngularUI Bootstrap创建模式对话框时,会创建一个新的子范围。

这意味着$scope中的ModalInstanceCtrl实际上是HTML范围的父范围。 (不要问我为什么这样建造它。)

要证明这一点,请更改

ng-model="selectedItem"ng-model="$parent.selectedItem"

并更改

Selected: <b>{{ selectedItem }}</b>Selected: <b>{{ $parent.selectedItem }}</b>

瞧!它有效。

更好的解决方案是更改ok()方法以接受子范围selectedItem,如下所示:

ng-click="ok(selectedItem)"

// Then, in the controller
$scope.ok = function (selectedItem) {
    $modalInstance.close(selectedItem);
};

有关正在发生的事情的更完整说明,请阅读this article

答案 1 :(得分:2)

除了在控制器中创建的HTML之外,它似乎为模式内的HTML创建子范围。打开模态时,请参阅this plunker中的ID。

所以要点是你在孩子的范围内设置'selectedItem',这在你可以在模态实例控制器中访问的范围内不可用。有两种方法可以解决这个问题:

选项1 在'ok'函数中取一个参数并将结果传递给HTML (plunker)

<button class="btn btn-primary" ng-click="ok(selectedItem)">OK</button>

JS:

$scope.ok = function (arg) {
  $modalInstance.close(arg);
};

选项2 在控制器中创建一个将继承到子范围以设置属性的对象。这就是sample code的作用。

selectedItem由angular设置时,它在您的控制器一无所知的子范围上设置,并且它不会传播到父范围。如果在继承的对象上设置值,它将更改继承对象的属性,您可以在控制器(plunker)中访问它:

<select
     ng-model="selected.Item"
     ng-options="item for item in items">
</select>

JS:

$scope.ok = function () {
  $modalInstance.close($scope.selected.Item);
};

答案 2 :(得分:0)

更改

    $modalInstance.close($scope.selectedItem);

    $modalInstance.close($scope.selected.item);

并在html中

    <div class="modal-body">
        <select
             ng-model="selected.item"
             ng-options="item for item in items">
        </select>
        Selected: <b>{{ selected.item }}</b>
    </div>

更新了plnkr - http://plnkr.co/edit/TuwPqtNeQwBVeXU2ncIe?p=preview