我想创建一些以某种方式与父控制器/范围交互的指令。我以 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 请帮助我!