Angular UI模式的范围问题

cob*_*blr 80 javascript scope modal-dialog angularjs angularjs-scope

我无法理解/使用角度UI模式的范围.

虽然这里没有立即显示,但我已经正确设置了模块和所有设置(据我所知),但这些代码示例特别是我发现错误的地方.

index.html(它的重要部分)

<div class="btn-group">
    <button class="btn dropdown-toggle btn-mini" data-toggle="dropdown">
        Actions
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu pull-right text-left">
        <li><a ng-click="addSimpleGroup()">Add Simple</a></li>
        <li><a ng-click="open()">Add Custom</a></li>
        <li class="divider"></li>
        <li><a ng-click="doBulkDelete()">Remove Selected</a></li>
    </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

Controller.js(再次,重要部分)

MyApp.controller('AppListCtrl', function($scope, $modal){
    $scope.name = 'New Name';
    $scope.groupType = 'New Type';

    $scope.open = function(){
        var modalInstance = $modal.open({
            templateUrl: 'partials/create.html',
            controller: 'AppCreateCtrl'
        });
        modalInstance.result.then(function(response){

            // outputs an object {name: 'Custom Name', groupType: 'Custom Type'}
            // despite the user entering customized values
            console.log('response', response);

            // outputs "New Name", which is fine, makes sense to me.                
            console.log('name', $scope.name);

        });
    };
});

MyApp.controller('AppCreateCtrl', function($scope, $modalInstance){
    $scope.name = 'Custom Name';
    $scope.groupType = 'Custom Type';

    $scope.ok = function(){

        // outputs 'Custom Name' despite user entering "TEST 1"
        console.log('create name', $scope.name);

        // outputs 'Custom Type' despite user entering "TEST 2"
        console.log('create type', $scope.groupType);

        // outputs the $scope for AppCreateCtrl but name and groupType
        // still show as "Custom Name" and "Custom Type"
        // $scope.$id is "007"
        console.log('scope', $scope);

        // outputs what looks like the scope, but in this object the
        // values for name and groupType are "TEST 1" and "TEST 2" as expected.
        // this.$id is set to "009" so this != $scope
        console.log('this', this);

        // based on what modalInstance.result.then() is saying,
        // the values that are in this object are the original $scope ones
        // not the ones the user has just entered in the UI. no data binding?
        $modalInstance.close({
            name: $scope.name,
            groupType: $scope.groupType
        });
    };
});
Run Code Online (Sandbox Code Playgroud)

create.html(完整版)

<div class="modal-header">
    <button type="button" class="close" ng-click="cancel()">x</button>
    <h3 id="myModalLabel">Add Template Group</h3>
</div>
<div class="modal-body">
    <form>
        <fieldset>
            <label for="name">Group Name:</label>
            <input type="text" name="name" ng-model="name" />           
            <label for="groupType">Group Type:</label>
            <input type="text" name="groupType" ng-model="groupType" />
        </fieldset>
    </form>
</div>
<div class="modal-footer">
    <button class="btn" ng-click="cancel()">Cancel</button>
    <button class="btn btn-primary" ng-click="ok()">Add</button>
</div>
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:为什么范围不是UI的双重约束?为什么this有自定义值,但$scope不是?

我试图ng-controller="AppCreateCtrl"在create.html中添加到body div,但是这引发了一个错误:"未知的提供者:$ modalInstanceProvider < - $ modalInstance"所以那里没有运气.

在这一点上,我唯一的选择是使用this.namethis.groupType不是使用传回一个对象$scope,但这感觉不对.

Nik*_*los 66

当涉及嵌套作用域时,不要将<input>s直接绑定到作用域的成员:

<input ng-model="name" /> <!-- NO -->
Run Code Online (Sandbox Code Playgroud)

将它们绑定到至少更深的水平:

<input ng-model="form.name" /> <!-- YES -->
Run Code Online (Sandbox Code Playgroud)

原因是范围原型继承其父范围.因此,在设置第一级成员时,这些成员直接设置在子范围上,而不会影响父级.与此相反,当绑定到嵌套字段(form.name)时,form会从父作用域读取成员,因此访问该name属性将访问正确的目标.

在此处阅读更详细的说明.

  • 将此更改为'form.name'时没有做任何事情,将其更改为ng-model ="$ parent.name"修复了问题.谢谢!(还要感谢阅读材料.还没看过这个.) (14认同)
  • @Nikos Paraskevopoulos,"form.name"代表什么?在提供的代码中根本没有提到它! (2认同)

Jas*_*ett 60

我让我这样工作:

var modalInstance = $modal.open({
  templateUrl: 'partials/create.html',
  controller: 'AppCreateCtrl',
  scope: $scope // <-- I added this
});
Run Code Online (Sandbox Code Playgroud)

没有表格名称,没有$parent.我正在使用AngularUI Bootstrap版本0.12.1.

我通风报信该解决方案通过.


ger*_*tas 7

2014年11月更新:

实际上你的代码应该在升级到ui-bootstrap 0.12.0后工作.Transcluded范围与控制器的范围合并,因此不再需要$parentform.填充.

在0.12.0之前:

模态使用transclusion来插入其内容.多亏了ngForm你可以按name属性控制范围.因此,为了逃避转换范围,只需以这种方式修改表单:

<form name="$parent">
Run Code Online (Sandbox Code Playgroud)

要么

<form name="$parent.myFormData">
Run Code Online (Sandbox Code Playgroud)

模型数据将在控制器范围内提供.