我一直在尝试从指令的组合中获得动态的行为。这是我用于sampler.js和index.html的代码:
"use strict";
var app = angular.module("myApp", []);
var Sampler = (function () {
function Sampler(sampler) {
this.sampler = sampler;
this.name = null;
this.value = null;
if (sampler) {
this.name = sampler.name;
this.value = sampler.value;
}
}
Sampler.prototype.getTemplateFor = function (file) {
return 'templates/' + name + '/' + file + '.html';
};
Sampler.prototype.addA = function () {
this.value = 'A';
};
Sampler.prototype.addB = function () {
this.value = 'B';
};
Sampler.create = function (name) {
var samplerClass = name + 'Sampler';
var items = samplerClass.split('.');
var creator = (window || this);
for (var i = 0; i < items.length; i++) {
creator = creator[items[i]];
}
if (typeof creator !== 'function') {
throw new Error('Class named ' + samplerClass + ' not found.');
}
var sampler = new creator({
name: name
});
if (!(sampler instanceof Sampler)) {
throw new Error(name + ' is not instance of Sampler.');
}
return sampler;
};
return Sampler;
}());
app.directive("sampler", function ($compile) {
return {
restrict: "E",
scope: { result: '=' },
link: function (scope, element, attributes) {
var name = !attributes.name ? '' : attributes.name;
var sampler = Sampler.create(name);
scope.sampler = sampler;
var template = '<div class="sampler form-horizontal">' +
' <sampler-item ng-if="!!sampler.value" sampler="sampler" />' +
' <sampler-new ng-if="!sampler.value" sampler="sampler" />' +
'</div>';
if (name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('sampler'),
success: function (response) { template = response; },
});
}
var content = $compile(template)(scope);
element.replaceWith(content);
scope.$watch('sampler.value', function () {
scope.result = scope.sampler.value;
});
}
};
});
app.directive("samplerNew", function ($compile) {
return {
restrict: "E",
scope: { sampler: '=' },
link: function (scope, element) {
var sampler = scope.sampler;
var template = '\
<div class="new">\
<button type="button" class="btn btn-default" ng-click="sampler.addA()">Add A</button>\
<button type="button" class="btn btn-default" ng-click="sampler.addB()">Add B</button>\
</div>';
if (sampler.name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('new'),
success: function (response) { template = response; },
});
}
var content = $compile(template)(scope);
element.replaceWith(content);
}
};
});
app.directive("samplerItem", function ($compile) {
return {
restrict: "E",
scope: { sampler: '=' },
link: function (scope, element) {
var sampler = scope.sampler;
var template = '\
<div class="item">\
Item: {{sampler.value}}\
</div>';
if (sampler.name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('sampler'),
success: function (response) { template = response; },
});
}
var content = $compile(template)(scope);
element.replaceWith(content);
}
};
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TypeScript HTML App</title>
</head>
<body ng-app="myApp">
<sampler result="result"></sampler>
Expression: {{result}}
<script src="lib/jquery/jquery-3.1.1.js"></script>
<script src="lib/angular/js/angular.js"></script>
<script src="js/directives/sampler.js"></script>
</body>
</html>
页面加载时,输出为:
按下按钮后,预期结果应为:
但是结果是:
请注意,我正在使用链接加载模板,因为我需要加载一个动态模板,其后备状态为默认模板。
如果我使用指令的template属性,则认为工作正常,但由于动态模板,这不适合我,因此请不要将此作为答案发送。
有人可以帮我吗?谢谢
我感谢Stephen Tillman(https://stackoverflow.com/users/7181162/stephen-tillman)的回答,这是一个可行的解决方案。但是,在对问题进行了更多修改之后,我发现了一种解决方案,其性能与我的预期完全相同。
主要解决方案是拥有行为ngIfDirective指令,并将其替换为我们自己的实现。另外,我们还必须记住在执行replaceWith(而不是追加)之后,用新元素替换原始元素。
这是sampler.ts的代码,其工作完全按预期进行:
// <reference path="../../lib/typings/jquery/jquery.d.ts" />
// <reference path="../../lib/typings/angular/angular.d.ts" />
"use strict";
interface ISampler {
name: string;
value: string;
getTemplateFor(file: string): string;
addA(): void;
addB(): void;
clear(): void;
}
class Sampler implements ISampler {
public name: string = null;
public value: string = null;
constructor(public sampler?: ISampler) {
if (sampler) {
this.name = sampler.name;
this.value = sampler.value;
}
}
public getTemplateFor(file: string): string {
return 'templates/' + name + '/' + file + '.html';
}
public addA(): void {
this.value = 'A';
}
public addB(): void {
this.value = 'B';
}
public clear(): void {
this.value = null;
}
static create(name: string): ISampler {
var samplerClass = name + 'Sampler'
var items = samplerClass.split('.');
var creator = (window || this);
for (var i = 0; i < items.length; i++) {
creator = creator[items[i]];
}
if (typeof creator !== 'function') {
throw new Error('Class named ' + samplerClass + ' not found.');
}
var sampler = new creator(<ISampler>{
name: name
});
if (!(sampler instanceof Sampler)) {
throw new Error(name + ' is not instance of Sampler.');
}
return sampler;
}
}
app.directive("sampler", ($compile) => {
return {
restrict: "E",
scope: { result: '=' },
link: ($scope: ng.IScope | any, $element, $attrs) => {
var name = !$attrs.name ? '' : $attrs.name;
var sampler = Sampler.create(name);
$scope.sampler = sampler;
var template =
'<div class="sampler form-horizontal">' +
' <sampler-item ng-if="!!sampler.value" sampler="sampler"></sampler-item>' +
' <sampler-new ng-if="!sampler.value" sampler="sampler"></sampler-new>' +
'</div>';
if (name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('sampler'),
success: (response) => { template = response; },
});
}
var newElement = $compile(template)($scope);
$element.replaceWith(newElement);
$element = newElement;
$scope.$watch('sampler.value', () => {
$scope.result = $scope.sampler.value;
});
}
}
});
app.directive("samplerNew", (ngIfDirective, $compile) => {
var ngIf = ngIfDirective[0];
return {
restrict: "E",
priority: ngIf.priority + 1,
terminal: true,
scope: { sampler: '=' },
link: ($scope: ng.IScope | any, $element, $attrs) => {
var sampler = $scope.sampler;
var comment = '<!-- show: ' + $attrs.show + ' -->';
var template = '\
<div class="new">\
<button type="button" class="btn btn-default" ng-click="sampler.addA()">Add A</button>\
<button type="button" class="btn btn-default" ng-click="sampler.addB()">Add B</button>\
</div>';
if (sampler.name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('new'),
success: (response) => { template = response; },
});
}
$scope.$watch($attrs.ngIf, (isVisible) => {
var newElement = $compile(isVisible ? template : comment)($scope);
$element.replaceWith(newElement);
$element = newElement;
});
}
};
});
app.directive("samplerItem", (ngIfDirective, $compile) => {
var ngIf = ngIfDirective[0];
return {
restrict: "E",
priority: ngIf.priority + 1,
terminal: true,
scope: { sampler: '=' },
link: ($scope: ng.IScope | any, $element, $attrs) => {
var sampler = $scope.sampler;
var comment = '<!-- show: ' + $attrs.show + ' -->';
var template = '\
<div class="item">\
Item: {{sampler.value}}<br />\
<button type="button" class="btn btn-default" ng-click="sampler.clear()">Clear</button>\
</div>';
if (sampler.name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('new'),
success: (response) => { template = response; },
});
}
$scope.$watch($attrs.ngIf, (isVisible) => {
var newElement = $compile(isVisible ? template : comment)($scope);
$element.replaceWith(newElement);
$element = newElement;
});
}
};
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句