5

我想创建一些以某种方式与父控制器/范围交互的指令。我以 2 种方式进行 CRUD:A)基于路由,如果您要编辑项目,我使用 $location 将 url 更改为给定的 url B)基于相同页面,如果您单击项目上的编辑,它会设置 $scope .template 来自 $scope.tpl,然后在部分中我有一个 ng-hide / show 隐藏和显示表格视图/详细视图。

我想要实现的可能是指令中的代码更少,并且可能使用更多基于服务的方法或提示?

指令

'use strict';

/* Directives */
var directives = angular.module("app.directives", ["ui"]);


function CrudCtrl($scope, $attrs, $location, $parse) {
    function getScope(scopeName) {
        scopeName = typeof scopeName || "$parent";
        var ngModel = $parse(scopeName, $scope);
        return ngModel($scope)
    }

    function refreshObjects(scopeName) {
        $scope.svc.query($scope.params, function(objects) {
            var parentScope = getScope(scopeName)
            parentScope.objects = objects
        });
    }

    if (!$scope.refreshObjects) {
        $scope.refreshObjects = function() {
            refreshObjects($attrs.modelname)
        }
    }

    if (!$scope.crudAdd) {
        $scope.crudAdd = function() {
            if ($attrs.url) {
                $location.path($attrs.url);
                return;
            } else {
                var parentScope = getScope($attrs.scope);
                parentScope.object = new $scope.svc();
                parentScope.template = parentScope.tpl;
            }
        }
    }

    if (!$scope.crudDelete) {
        $scope.crudDelete = function() {
            /* Fire off a delete and as a callback we update objects */
            $scope.svc.delete({accountId: $scope.account.uuid, id: $scope.object.id}, function() {
                refreshObjects($attrs.scopeName)
            });
        };
    }

    if (!$scope.crudEdit) {
        $scope.crudEdit = function() {
            if ($attrs.url) {
                $location.path($attrs.url);
                return;
            } else {
                var parentScope = getScope($attrs.scopeName);
                parentScope.object = $scope.object;
                parentScope.template = parentScope.tpl;
            }
        };
    }

    if (!$scope.crudSave) {
        $scope.crudSave = function() {
            var params = {}
            params.accountId = $scope.params.accountId
            if ($scope.object.id) { params.id = $scope.object.id }

            $scope.object.$save(params, function() {
                if ($attrs.url) {
                    $scope.back();
                } else {
                    refreshObjects($attrs.scopeName);

                    var parentScope = getScope($attrs.scopeName);
                    parentScope.template = undefined;
                }
            });
        };
    }

    if (!$scope.crudCancel) {
        $scope.crudCancel = function() {
            if (parentScope.template) {
                var parentScope = getScope($attrs.scopeName);
                parentScope.template = undefined;
            } else {
                $scope.back();
            }
        };
    };
};


directives.directive("refresh", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-mini btn-primary" ng-click="refreshObjects()"><i class="icon-refresh"></i> Refresh</button>',
    };
});


/* Create something new */
directives.directive("create", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-mini btn-success" ng-click="crudAdd()"><i class="icon-plus"></i> {{display_text || "Add"}}</button>',
    };
});


/* Delete button and update objects */
directives.directive("delete", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-mini btn-danger" ng-click="crudDelete()"><i class="icon-remove icon-white"></i> {{display_text}}</button>',
    }
});

/* Helper to create a edit button */
directives.directive("edit", function() {
    return {
        restrict: "E",
        replace:  true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-mini btn-info" ng-click="crudEdit()"><i class="icon-edit"></i> {{display_text || "Edit"}}</a>',
    }
});

/* Save the object and return to the previous page */
directives.directive("save", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-success" ng-click="crudSave()"><i class="icon-ok"> {{display_text || "Save"}}</i></a>',
    };
});

/* Cancel the current action */
directives.directive("cancel", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn" ng-click="crudCancel()"><i class="icon-remove"></i> {{display_text || "Cancel"}}</button>'
    }
});

示例控制器

function BookingCtrl($scope, Booking) {
      $scope.svc = Booking;
      $scope.objects = $scope.svc.query($scope.params);
  }

然后在部分概述中,我有:

<div ng-hide="template">
<refresh></refresh>
<create url="/{{params.accountId}}/entity/add"></create>

<table class="table table-condensed table-hover">
    <thead>
        <tr>
            <th></th>
            <th>Name</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="object in objects">
            <td>
                <delete></delete>
                <edit url="/{{params.accountId}}/category/{{object.resource_id}}"></edit>
            </td>
            <td>{{object.resource_name}}</td>
            <td>{{object.description}}</td>
        </tr>
        </tr>
        </tr>
    </tbody>
</table>
</div>

<ng-show="template" ng-include src="template"></ng-show>

细节部分:

<div class="span4">
    <h3>Category: {{category.resource_name}}</h3>
    <form name="detail_form" class="form-horizontal">
        <div class="control-group">
            <label class="control-label"><strong>Name</strong></label>
            <div class="controls">
                <input required ng-model="object.resource_name" placeholder="Name" type="text" class="input-small">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label"><strong>Description</strong></label>
            <div class="controls">
                <textarea ng-model="object.description" placeholder="Description" type="textarea" rows=5></textarea>
            </div>
        </div>
        <div class="control-group">
            <save scope-name="$parent.$parent"></save>
            <cancel scope-name="$parent.$parent"></cancel>
        </div>
    </form>
<pre>form = {{object | json}}</pre>
</div>

如果有更好的方法来解决这个问题,这似乎过度使用 $parent.$parent 请帮助我!

4

1 回答 1

2

我会通过以下方式处理这种功能:

  • 投入$resource使用。
  • 用于ng-view绑定 url 和 partials。使用锚链接到其他部分。
  • 根据角色为每个部分定义控制器。($resource通过服务访问)

http://angularjs.org/#wire-up-a-backend可能就是一个例子。

于 2012-10-15T21:44:51.143 回答