【问题标题】:AngularJS - Issues with events inside controller instances generated by ng-repeatAngularJS - ng-repeat 生成的控制器实例内的事件问题
【发布时间】:2013-09-25 01:06:51
【问题描述】:

今天我遇到了一个听起来很奇怪的问题,但肯定有一些合乎逻辑的解释......

我正在构建一个允许内联编辑字段值的表格。例如,您会看到一个带有标题的跨度,然后如果您单击它,就会出现内联编辑。

这是 ng-repeat 的包装器

<div ng-repeat="product in products" ng-controller="ProductController">
</div>

如您所见,每次迭代都会创建 ProductController 的新实例。产品控制器触发一些事件,并相应地捕获它们。

myApp.controller('ProductController', function ($scope, $filter, $http, $document) {
//Show publications flag
$scope.showPublications = false;

//Inline edition object
$scope.inlineEdition = {
    enabled: false,
    title: false,
    sku: false,
    realstock: false,
    minstock: false
};

$document.bind('click', function(e) {
    e.stopPropagation();

    //Dispatch an event
    $scope.$emit("documentclick");
});

angular.element(".dev-inline-editor").bind('click', function(e) {
    e.stopPropagation();
});

angular.element(".inline-edit").bind('click', function(e) {
    e.stopPropagation();
    //Dispatch an event
    $scope.$broadcast("inlineEditWrapperClicked",[$scope.inlineEditionGetStatus('enabled')]);   
});

angular.element(".inventory-field span").bind('click', function(e) {
    e.stopPropagation();
});

$scope.$on("inlineEditWrapperClicked", function(e, inlineStatus) {
    if(inlineStatus[0] === true) {
        $scope.$apply(function () {
            $scope.terminateInlineEdition();
            e.stopPropagation();
        })
    }
});

$scope.$on("documentclick", function (e) {
    $scope.$apply(function() {
        $scope.terminateInlineEdition();
    })

});

 //Code goes on...

然后是标记...

<div class="inventory-field inventory-row-minstock inline-edit inline-edit-regular">
   <span ng-hide="inlineEditionGetStatus('minstock')" ng-click="setInlineEdition('minstock')">{{product.min_stock}}</span>
   <div ng-show="inlineEditionGetStatus('minstock')" class="dev-inline-editor clearfix">      <input  type="text" ng-model="product.min_stock" />
    <input type="button" ng-click="inlineEditionEnd('minstock')" value="Ok" />
   </div>
</div>

inlineGetStatus 返回真或假。它应该将编辑器隐藏在一个真值上,这解释了为什么 $scope.$on("inlineEditWrapperClicked" 需要一个真值。

主 div 内的 span 显示字段值,单击时显示输入。想法是当你点击内联编辑器外部时,它会消失,span会恢复到可见状态。

一切都像一个魅力......但是......

例如,当我有一个包含三行的表格时,我可以打开三个内联编辑器,单击它们一次。一切都很好,直到那里。如果我在最后一行的编辑器外部单击,该编辑器将被隐藏,并且显示字段值的跨度将恢复。但是如果我在第一行的第一个编辑器之外单击,则第一、第二和第三个编辑器将同时隐藏。这似乎是控制器实例向下的连锁效应。

我尝试过使用 $emit、$broadcast,但似乎没有任何东西可以解决不希望出现的效果。我被困在这里,所以如果有人能启发我,我将不胜感激。

真正奇怪的是,每次我记录一个来自getter getInlineEditorStatus(); 的属性时。它返回的日志与我拥有的控制器实例(或行)一样多。我无法仅访问我需要的范围实例。

我真的很想提前感谢你们能给我的任何帮助。

问候,

吉列尔莫

【问题讨论】:

  • $scope.$on("documentclick", function (e) { $scope.$apply(function() { $scope.terminateInlineEdition(); }) });原本在子控制器外,在主控制器内,但问题是一样的。

标签: javascript angularjs angularjs-scope angularjs-ng-repeat


【解决方案1】:

您可以为内联编辑器创建一个具有隔离范围的指令,并为页面使用单个控制器。这将有几个优点,首先内联编辑器可以很容易地在其他地方重用,并且页面控制器可能更容易处理,因为只有一个实例。我认为这也可以解决您遇到的错误。

像这样在一个 ng-repeat 中创建多个控制器让我感觉很奇怪......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    相关资源
    最近更新 更多