简体   繁体   English

Angular UI模式的范围问题

[英]Scope issues with Angular UI modal

I'm having trouble understanding/using the scopes for an angular UI modal. 我无法理解/使用角度UI模式的范围。

While not immediately apparent here, I have the modules and everything set up correctly (as far as I can tell), but these code samples in particular are where I'm finding the bug. 虽然这里没有立即显示,但我已经正确设置了模块和所有设置(据我所知),但这些代码示例特别是我发现错误的地方。

index.html (the important part of it) 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>

Controller.js (again, the important part) 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
        });
    };
});

create.html (in its entirety) 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>

So, my question stands: why is the scope not being double-bound to the UI? 所以,我的问题是:为什么范围不是UI的双重约束? and why does this have the customized values, but $scope does not? 为什么this有自定义值,但$scope不?

I have tried to add ng-controller="AppCreateCtrl" to the body div in create.html, but that threw an error: "Unknown provider: $modalInstanceProvider <- $modalInstance" so no luck there. 我试图将ng-controller="AppCreateCtrl"到create.html中的body div,但是这引发了一个错误:“Unknown provider:$ modalInstanceProvider < - $ modalInstance”所以没有运气。

At this point, my only option is to pass back an object with this.name and this.groupType instead of using $scope , but that feels wrong. 此时,我唯一的选择是使用this.namethis.groupType传回一个对象而不是使用$scope ,但这感觉不对。

When nested scopes are involved, do not bind <input> s directly to members of the scope: 当涉及嵌套作用域时,不要将<input>直接绑定到作用域的成员:

<input ng-model="name" /> <!-- NO -->

Bind them to at least a level deeper: 将它们绑定到至少更深的水平:

<input ng-model="form.name" /> <!-- YES -->

The reason is that scopes prototypically inherit their parent scope. 原因是范围原型继承其父范围。 So when setting 1st level members, these are set directly on the child scope, without affecting the parent. 因此,在设置第一级成员时,这些成员直接设置在子范围上,而不会影响父级。 In contrast to that, when binding to nested fields ( form.name ) the member form is read from the parent scope, so accessing the name property accesses the correct target. 与此相反,当绑定到嵌套字段( form.name )时,会从父作用域中读取成员form ,因此访问name属性将访问正确的目标。

Read a more detailed description here . 在此处阅读更详细的说明。

I got mine to work like this: 我让我这样工作:

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

No form name, no $parent . 没有表格名称,没有$parent I'm using AngularUI Bootstrap version 0.12.1. 我正在使用AngularUI Bootstrap版本0.12.1。

I was tipped off to this solution by this . 我通风报信该解决方案通过

Update Nov 2014 : 2014年11月更新

Actually your code should work after upgrading to ui-bootstrap 0.12.0. 实际上你的代码应该在升级到ui-bootstrap 0.12.0后工作。 Transcluded scope is merged with controller's scope so no more need for $parent or form. Transcluded范围与控制器的范围合并,因此不再需要$parentform. stuff. 东西。

Before 0.12.0 : 在0.12.0之前

The modal uses transclusion to insert its contents. 模态使用transclusion来插入其内容。 Thanks to ngForm you can control the scope by name attribute. 感谢ngForm您可以按name属性控制范围。 So to escape transcluded scope just modify the form this way: 因此,为了逃避转换范围,只需以这种方式修改表单:

<form name="$parent">

or 要么

<form name="$parent.myFormData">

The model data will be available in controller scope. 模型数据将在控制器范围内提供。

$scope.open = function () {

          var modalInstance = $uibModal.open({
              animation: $scope.animationsEnabled,
              templateUrl: 'myModalContent.html',
              controller: 'salespersonReportController',
              //size: size
              scope: $scope
            });

      };

it works for me scope: $scope thank u Jason Swett 它适用于我的范围:$ scope谢谢你Jason Swett

我添加范围:$ scope然后它工作.Cool

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

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