从指令广播到控制器

时间:2016-01-20 06:52:33

标签: angularjs

我正在尝试通过我的指令模板中的按钮修改视图中的表单(模板在另一个文件中),这是一个基本的CRUD,其中每个项目都有一个删除/编辑按钮。

为了避免复制表单,我决定在编辑单击时单击一个函数会将项目发送到控制器中以便更新新信息。

但是我在连接时遇到了麻烦,到目前为止,我尝试来回更改$root$rootScope并使用,$broadcast$emit

那么如何发送功能onChange我的项目信息基于模板的按钮点击?

模板:

<strong>{{item.type}}</strong> {{item.description}}

<div class="material-switch pull-right">


    <button type="button" class="btn btn-warning btn-circle"  ng-show="item.editable" ng-click="onChange()">
        <span class="glyphicon glyphicon-edit" ></span>
    </button>

    <button type="button" class="btn btn-danger btn-circle" ng-controller="View1Ctrl" ng-show="item.editable" ng-click="EliminarItem(item)">
        <span class="glyphicon glyphicon-minus" ></span>
    </button>


    <input ng-model="item.isDone" 
        id="someSwitchOptionDefault{{itemIndex}}" 
        name="someSwitchOption001{{itemIndex}}" 
        type="checkbox" /> 
        <label for="someSwitchOptionDefault{{itemIndex}}" class="label-info"></label>
</div>

指令

'use strict';

angular.module('myApp.items.directive', [])

.directive('itemSwitch', [ function() {
    return {
        restrict: 'A',
        scope: {
            item: '=',
            itemIndex: "="
        },
        templateUrl: 'templates/itemSwitchTemplate.html',
        link : function($scope){
            $scope.$broadcast('onChange', item);
        }
    }
}]);

控制器

.controller('View1Ctrl', ['$scope','itemsService',function($scope,itemsService) {
    $scope.items = itemsService.getItems();
    $scope.classMap = {GROCERIES:"success",CAR:"danger",UNIVERSITY:"warning",PAYMENTS:"info"};
    $scope.newItem = {};


    $scope.$on('onChange', function(event, args) {

        if ($scope.btnEdit) {

             $scope.newItem = args;
        } else {
             $scope.newItem = {};
        } 

    });


    $scope.enableEdit = function (item) {

                item.editable = true;
            };

    $scope.disableEdit = function (item) {

                item.editable = false;

            };

}]);

查看

        <div class="col-xs-12">
            <div ng-model="currentItem" ng-repeat="item in items" item-switch item="item" item-index="$index" class="notice notice-{{classMap[item.type]}}" ng-mouseover="enableEdit(item)" ng-mouseleave="disableEdit(item)">
            </div>


<!-- FORMULARIO -->

    <form name = "myForm" class="form-horizontal">
      <fieldset>
        <div id="legend">
          <legend class="">Task</legend>
        </div>

        <div class="control-group">
          <!-- Name-->
          <label class="control-label">Name</label>
          <div class="controls">
            <input type="text" name="itemName" ng-model="newItem.name" placeholder="Task Name" class="input-xlarge"  ng-required="true" >
            <p class="help-block"></p>
          </div>
        </div>

        <div class="control-group">
          <!-- Description -->
          <label class="control-label">Description</label>
          <div class="controls" >
            <input type="text" ng-model="newItem.description" placeholder="Task Description" class="input-xlarge">
            <p class="help-block"></p>
          </div>
        </div>

        <div class="control-group">
          <!-- Button -->
          <div class="controls">
            <a class="btn icon-btn btn-success" ng-disabled="myForm.$invalid" ng-click="addOrSaveItem()">
            <span class="glyphicon btn-glyphicon glyphicon-save img-circle text-success"></span>Save</a>
          </div>
        </div>

      </fieldset>
    </form>

        </div>

FiddleJS

看起来感觉

enter image description here

2 个答案:

答案 0 :(得分:2)

使用&#34; onChange&#34;作为事件名称是一个糟糕的选择,因为它可能与具有该名称的其他事件冲突。我的建议是使用指令的名称作为事件名称的一部分。

在您的指令

angular.module('myApp.items.directive', [])

.directive('itemSwitch', function() {
    return {
        restrict: 'A',
        scope: {
            item: '=',
            itemIndex: "="
        },
        template: '<button ng-click="doIt()">Do It</button>',
        link : function(scope){
            scope.doIt = function() {
                scope.$emit('itemSwitch.doIt', scope.item, scope.itemIndex);
            };
        }
    }
});

在您的控制器中

$scope.doItItems = [];
$scope.$on("itemSwitch.doIt", function(item, itemIndex) {
     doItItems.push(item);
});

在此示例中,每次单击Do It按钮时,项目都会被推送到doItItems列表。

答案 1 :(得分:0)

itemSwitch指令中,您可以执行

$rootScope.$broadcast('onChange', item);

然后你可以在任何正在聆听的范围内(在这种情况下,你的控制器)拿起它,

$scope.$on('onChange', function(event, args) { ... }

这是有效的,因为$broadcast从父级向下移动到子级,而$emit从子级向父级移动。

例如,$rootScope.$emit只会被$rootScope.$on选中,因为$rootScope没有父母,而$scope.$broadcast只能用于该范围的孩子,而不是$rootScope.$on,因为$rootScope不是$scope

的孩子