angularjs - 我可以在 Angular 服务中直接在 templateUrl 上而不是在原始 HTML 或原始 angular.element 上使用 $compile 吗?

标签 angularjs angularjs-service

鉴于以下旨在创建“对话”元素(即模式)的服务:

app.service('dialog', ['$document', '$compile', '$rootScope',
    function($document, $compile, $rootScope) {

        var body = $document.find('body');
        var scope = $rootScope.$new();

        this.createDialog = function() {
            var dialogElem = angular.element('<div ng-include="\'/dialog.html\'"></div>');
            $compile(dialogElem)(scope);
            body.append(dialogElem);
        };

    }
]);

可以在 Controller 中使用,如下所示:
$scope.someFunction = function() {
    dialog.createDialog();
};

有什么方法可以使用$compile或其他任何在我的服务中没有 HTML 的东西?我真的更喜欢只调用一个指令,以便运行 createDialog()立即将指令注入(inject)到我的 DOM 中,因此该指令负责将新 Controller 和模板链接在一起。如果我以错误的方式处理这个问题,我完全愿意接受 build 性的想法。

最佳答案

当然可以!,给你:

app.factory('modalService', function ($document, $compile, $rootScope, $templateCache, $http) {

    var body   = $document.find('body'),
        modals = [];

    var service = {
        show: function (template, data, modal) {

            // The template's url
            var url = 'template/modal/' + template + '.html';

            // A new scope for the modal using the passed data
            var scope = $rootScope.$new();
            angular.extend(scope, data);

            // Wrapping the template with some extra markup
            modal = modal || angular.element('<div class="modal"/>');

            // The modal api
            var api = {
                close: function () {

                    modal.remove();
                    scope.$destroy();
                    modals.splice(modals.indexOf(api), 1);

                },
                replace: function (template, data) {

                    return angular.extend(api, service.show(template, data, modal));
                }
            };

            // Adding the modal to the body
            body.append(modal);

            // A close method
            scope.close = api.close;

            // Caching the template for future calls
            $http.get(url, {cache: $templateCache})
                .then(function (response) {

                    // Wrapping the template with some extra markup
                    modal.html('<div class="win">' + response.data + '</div>');

                    // The important part
                    $compile(modal)(scope);
                });

            modals.push(modal);

            return api;
        },
        showOrReplaceLast: function (template, data) {

            return service.show(template, data, modals.length > 0 ? modals[modals.length - 1] : null);
        }
    };

    return service;
});

一些注意事项:
  • 您需要在 DOM 中的某处插入模式,这就是注入(inject) $document 的原因。
  • 是的,您可以将模态标记移出此处。
  • 请记住为对话框创建新范围并销毁它们($rootScope.$new)。
  • 这是一个WIP,我希望它足够清楚。
  • 关于angularjs - 我可以在 Angular 服务中直接在 templateUrl 上而不是在原始 HTML 或原始 angular.element 上使用 $compile 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26109658/

    相关文章:

    javascript - 如何更改 Angular 值配方中的存储值

    javascript - AngularJS - 动态 DOM 操作,无需在 Controller 中硬编码 dom id

    angularjs - 如何在 angularjs 中用 2 个相同的 Controller 制作原型(prototype)?

    javascript - 填写表单时将按钮设置为事件状态( Angular )

    angularjs - 如何使用 angularjs 检测浏览器?

    c# - JSON 中出现意外标记

    Angularjs - 工厂/服务内的 Restangular 调用

    javascript - AngularJS $ 注入(inject)器 :unpr issue with Angular Bootstrap modal

    angularjs - 在 AngularJS 中创建自定义对象

    javascript - Angularjs - 将服务代码移动到另一个文件