javascript - Angular Directive(指令)的行为不符合预期。我需要一些帮助来找出原因

标签 javascript jquery angularjs

我一直在尝试从指令组合中获得动态行为。 这是我用于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>

当页面加载时,输出是:

After page loads

按下按钮后,预期结果应该是:

Expected result

但结果是:

Actual result

请注意,我使用链接来加载模板,因为我需要加载一个动态模板并回退到默认模板。

如果我使用指令的模板属性,则认为效果很好,但由于动态模板,这不适合我,因此请不要将其作为答案发送。

有人可以帮我吗? 谢谢

最佳答案

在你之后$compile samplerNew 的模板指令,那么您正在使用编译后的 content替换原始元素 - 具有 ng-if 的元素属性。因此,ng-if<sampler-new> 没有影响元素,因为每次渲染时它都会被替换。

所以,尝试使用你的ng-if属性关闭 <sampler-new>元素并将其放在 <div class="new"> 上编译 samplerNew 的元素指令。

修复

  1. 转到您的 sampler指令
  2. 查找string分配给 template 的文字link 内的变量功能
  3. ng-if="!sampler.value"来自<sampler-new>元素
  4. 向下滚动到您的samplerNew指令
  5. 查找string分配给 template 的文字link 内的变量功能
  6. 粘贴ng-if="!sampler.value"转到<div class="new">元素

现在,当您单击Add A时或Add B按钮将消失,并且将显示您的项目表达式字段。

关于javascript - Angular Directive(指令)的行为不符合预期。我需要一些帮助来找出原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41215172/

相关文章:

c# - 压缩从 Angular 到 Web API 的请求

javascript - 动态更新 react-google-chart 类型

Javascript ParseInt() 为 -1

javascript - 获取正则表达式中的第六个匹配行

jquery selectable - 禁用相应的值

javascript - 如何检查是否已经有与元素关联的点击/事件

javascript - 自定义指令中范围对象内的嵌套对象

javascript - 在 .append 之后运行函数

javascript - Angular JS 分页

javascript - 带功能的 ionic 自动完成取消标签