【问题标题】:angular directive (2-way-data-binding) - parent is not updated via ng-click角度指令(2-way-data-binding) - 不通过 ng-click 更新父级
【发布时间】:2016-01-05 12:18:15
【问题描述】:

我有一个具有隔离范围的嵌套指令。一个对象数组通过 2 路数据绑定绑定到它。

.directive('mapMarkerInput',['mapmarkerService', '$filter', '$timeout',function(mapMarkerService, $filter, $timeout) {
    return {
        restrict: 'EA',
        templateUrl:'templates/mapmarkerInputView.html',
        replace: true,
        scope: {
            mapmarkers: '='
        },
        link: function($scope, element, attrs) {

            //some other code

            $scope.addMapmarker = function($event) {
                var mapmarker = {};
                var offsetLeft = $($event.currentTarget).offset().left,
                    offsetTop = $($event.currentTarget).offset().top;

                mapmarker.y_coord = $event.pageY - offsetTop;
                mapmarker.x_coord = $event.pageX - offsetLeft;
                mapmarker.map = $scope.currentMap;
                $scope.mapmarkers = $scope.mapmarkers.concat(mapmarker);
            };

            $scope.deleteMapmarker = function(mapmarker) {
                var index = $scope.mapmarkers.indexOf(mapmarker);
                if(index !== -1) {
                    $scope.mapmarkers.splice(index,1);
                }
            };

            //some other code
       )
}]);

这两个函数是通过 ng-click 触发的:

<img ng-if="currentMap" ng-click="addMapmarker($event)" ng-src="/xenobladex/attachment/{{currentMap.attachment.id}}" />
<div class="mapmarker-wrapper" ng-repeat="mapmarker in shownMapmarkers" ng-click="setZIndex($event)" style="position: absolute; top: {{mapmarker.y_coord}}px; left: {{mapmarker.x_coord}}px;">
     <!-- some other code -->
     <div class="form-group">
          <label>Name:</label>
          <input ng-model="mapmarker.name" value="mapmarker.name" class="form-control" type="text">
     </div>
     <div class="form-group">
          <label>Description:</label>
          <input ng-model="mapmarker.description" value="mapmarker.description" class="form-control" type="text">
     </div>
     <button class="btn btn-danger" ng-click="deleteMapmarker(mapmarker)">Delete</button>
</div>

如您所见,我直接通过 ng-model 绑定名称和描述,效果很好。这些属性在父范围内也可用,但删除和添加都不起作用(它在指令范围内更改,但在父范围内没有更改)。

据我了解,应该应用这些更改,因为我通过 ng-click 调用这些函数,并且我还有其他示例可以使用。唯一的区别是,我绑定到一个对象数组而不是单个对象/属性。

我尝试使用 $timerupdateParent()$scope.$apply() 不起作用 -> 抛出该函数已在摘要循环内的异常)但没有成功,因此看起来这些更改并未在全部。

指令代码如下所示:

<map-marker-input ng-if="$parent.formFieldBind" mapmarkers="$parent.formFieldBind"></map-marker-input>

它嵌套在一个自定义表单字段指令中,该指令动态获取正确的表单字段模板,因此将template: '&lt;div ng-include="getTemplate()"&gt;&lt;/div&gt;' 作为模板,这会创建一个新的子范围 - 这就是这里需要$parent 的原因。

绑定肯定以一种方式工作,预期数据在指令中可用,如果我在通过删除或添加更改数据后记录数据,它也是正确的,但仅限于指令内部。

因为ng-model 有效,我想可能有一个简单的解决方案。

更新

我创建了一个简化版本的 plunkr: http://plnkr.co/85oNM3ECFgCzyrSPahIr

只需单击蓝色区域内的任意位置,即可从 mapmarker 指令中添加新点。现在,如果您删除或编辑这些,我并不会真正阻止添加积分 - 所以您最终会很快获得很多积分;-)

有一个按钮可以显示来自父范围和来自子范围的数据。

如果您编辑一个现有点的名称或描述,该点也将在父范围内更改(通过ng-model 绑定)。但是所有新的点或删除都会被忽略(绑定在通过ng-click 调用的函数中)。

【问题讨论】:

  • 如果您创建 plunker 或 jsfiddle 让读者轻松重现您的问题会更好。
  • 如果你需要使用$parent,一般会有问题。除了在极少数情况下需要父索引之外,您不应该真的需要使用 $parent。如前所述,演示会有所帮助
  • 正如我在上面解释的那样,表单字段指令没有常规模板,因为模板是动态获取的,它看起来像这样:模板:'
    ' 并创建一个新的子范围。我将它用于许多不同的表单字段,它绝对正确,是的,在极少数情况下需要它;-) 我会看看我是否可以做一个小提琴,希望有人马上有一个想法,因为它适用于我的所有其他领域并使用 ng 模型。我编辑了我的问题,对表单字段模板进行了更好的解释。
  • 我创建了一个 plunkr 来重现这个问题
  • 看了演示,不知道该怎么做才能重现问题

标签: angularjs angularjs-directive 2-way-object-databinding


【解决方案1】:

如果你想更新父作用域,你需要再次通过 $parent 访问它, 我改变了

mapmarkers="$parent.formFieldBind"

到:

mapmarkers="$parent.$parent.formFieldBind"

ng-include 再创建一个范围,因此您需要再次访问父级。

http://plnkr.co/edit/27qF6ABUxIum8A3Hrvmt?p=preview

【讨论】:

  • 你说得对,它适用于双 $parent,非常感谢!但是你知道为什么没有 ng-model 也能正常工作吗?
  • 我也不明白为什么要创建两个子作用域......使用双 $parent 我仍在访问表单字段指令 scrope。它应该只有一个来自 ng-include 还是?我真的很想接受你的回答,但我需要更好地理解这个问题,以了解这是否是正确的解决方案(我正在对多个字段使用表单字段指令,这些指令与一个 $parent 一起工作得很好,因为我使用的是 ng-model,有时也使用 ng-change)。
  • 即使模型分配给未定义的变量,角度确实永远不会返回错误,这有时会导致头痛,
  • 一些本机指令,例如 ng-repeat,ng-include 使用 localscope 在其标记内创建“本地范围”,另一个指令如 ng-if,ng-click 不是。 localscope 用于将指令范围与父范围隔离。
  • 是的,我知道创建了 一个 隔离范围,因此需要一个 $parent ......但不是两个。此外,参数绝对不是未定义的,因为显示数据(演示中的一个现有点)并且“名称”和“描述”通过 ng-model 正确更新。我会接受你的回答,因为它解决了问题,而且似乎没有其他人会回答。也许我会找出这背后的真正问题,你至少给了我一个提示:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多