Angular指令的行为不符合预期。我需要一些帮助找出原因

安德烈·维安娜(Andre Vianna)

我一直在尝试从指令的组合中获得动态的行为。这是我用于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属性,则认为工作正常,但由于动态模板,这不适合我,因此请不要将此作为答案发送。

有人可以帮我吗?谢谢

安德烈·维安娜(Andre Vianna)

我感谢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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

isinstance()的行为不符合我的预期

来自分类Dev

Angular 自定义验证指令 - 错误行为不符合预期

来自分类Dev

XML转换行为不符合预期。我需要循环吗?

来自分类Dev

JsonIgnore和JsonProperty的行为不符合我的预期

来自分类Dev

Preg_replace的行为不符合我的预期

来自分类Dev

为什么if语句的行为不符合我的预期?

来自分类Dev

JsonIgnore和JsonProperty的行为不符合我的预期

来自分类Dev

Coffeescript类的行为不符合预期

来自分类Dev

SSLContext模拟行为不符合预期

来自分类Dev

类型n的行为不符合预期

来自分类Dev

CancellationTokenSource的行为不符合预期

来自分类Dev

WinWaitActive函数的行为不符合预期

来自分类Dev

变量的行为不符合预期

来自分类Dev

jQuery remove()行为不符合预期

来自分类Dev

Excel OR函数的行为不符合预期

来自分类Dev

强行“替换”行为不符合预期

来自分类Dev

reactValuesToList行为不符合预期

来自分类Dev

CancellationTokenSource的行为不符合预期

来自分类Dev

memcached测试的行为不符合预期

来自分类Dev

类型n的行为不符合预期

来自分类Dev

Coffeescript类的行为不符合预期

来自分类Dev

角度`watch`的行为不符合预期

来自分类Dev

primaryValues的行为不符合预期

来自分类Dev

autocmd行为不符合预期

来自分类Dev

while循环的行为不符合预期?

来自分类Dev

WinWaitActive函数的行为不符合预期

来自分类Dev

VBA词典的行为不符合预期

来自分类Dev

HashMap的行为不符合汉字的预期

来自分类Dev

MySQL查询的行为不符合预期