将Angular与MVC局部视图混合

时间:2015-08-04 09:35:04

标签: javascript .net asp.net-mvc angularjs asp.net-mvc-4

我需要什么

一系列屏幕,每个屏幕都会在按钮点击时打开下一个屏幕。必须折叠每个上一个屏幕,并且必须通过从MVC后端加载局部视图来添加新屏幕。

我有什么

具有以下功能的AngularJS控制器:

self.AddChild = function (uri, targetContainerId, collapseTitle, breadCrumbContainerId) {
    var target = $("#" + targetContainerId);

    if (target != 'undefined' && target != undefined && target.length > 0) {
        apiService.Get(uri).then(function (viewData) {
            self.CollapsePreviousChild(self.ChildCount);

            // Increase childcount by 1
            self.ChildCount += 1;

            // Set HTML data
            var html = '<div id="collapsibleScreen-"' + self.ChildCount + ' class="open">' + viewData + '</div>';

            target.html(html);

            // Update screens collapse status
            self.UpdateScreenBreadCrumb(collapseTitle, breadCrumbContainerId);
        });
    };
}

UpdateScreenBreadCrumb函数有效,否则无关。

它被称为(例如):

self.AddChild("/Partials/View1", "targetContainer", "View", "breadCrumbContainer");

它的作用

加载视图(表单)的内容,正确更新面包屑。

我需要修复的内容

在加载的局部视图上,有一个按钮定义如下:

<button class="btn btn-primary" ng-click="AddPartialView()">Add partial view</button>

单击该按钮无效。如果我添加一个console.log(&#39; Code就在这里。&#39;) AddPartialView(),它没有被记录。将ng-click值直接设置为alert(&#39; hello&#39;)也没有效果。

没有任何可见的错误。

有关如何使此按钮有效的任何建议吗?

2 个答案:

答案 0 :(得分:1)

关于您的问题,您正在添加不由Angular编译的HTML。您需要在新添加的HTML元素上使用$ compile,然后将其绑定到范围。 $ compile()函数返回一个link()函数,用于绑定范围。例如:

$compile(new-element)(scope-to-bind-to)

注意:您不应该通过控制器操纵DOM。这被认为是不好的做法。您应该使用自定义指令或Angular指令的一些组合(ngIf,ngSwitch,ngInclude)。我建议观看AngularJS best practices

答案 1 :(得分:1)

我按照Itamar L.的建议调查了$ compile并开始工作。我发现的样本也使用了指令,所以无论如何我都实现了它们:

angular.module('directives.api').directive("PartialViewLoader", [
    '$compile',
    'chainedScreensService',
    function (
        $compile,
        chainedScreensService) {
        return {
            restrict: 'A',
            scope: {
                view: '=',
                parent: '='
            },
            controller: function() {
            },
            link: function (scope, element, attrs) {

                chainedScreensService.GetPartialView(attrs.view).then(function (viewData) {
                    var linkFunc = $compile(viewData);
                    var content = linkFunc(scope);
                    element.append(content);

                    if (attrs.parent != 'undefined' && attrs.parent != undefined && attrs.parent.length > 0) {
                        chainedScreensService.CollapsePartialByIdentifier(attrs.parent);
                    }
                });
            }
        }
    }
]);

我这样用:

<div ng-controller="collapseController">
    <div id="breadCrumbContainer" style="display: inline"></div>
    <div id="mainContainer">
        <div id="personContainer" partial-view-loader view="persoon" parent="" class="open"></div>
    </div>
</div>

如上所述,它本身会显示第一页,其中有一个按钮指向下一页。在collapseController中找到的相关函数是:

self.AddNextScreen = function (parentViewIdentifier, targetContainerId, breadCrumbContainerId) {
    self.AddChildByDirective("NextScreen", parentViewIdentifier, targetContainerId, breadCrumbContainerId);
}

AddChildByDirective的代码:

self.AddChildByDirective = function (viewIdentifier, parentViewIdentifier, targetContainerId, breadCrumbContainerId) {
    var html = '<div id="' + viewIdentifier + 'Container" fvl-partial-view-loader view="' + viewIdentifier + '" parent="' + parentViewIdentifier + '" class="open"></div>';

    var target = $('#' + targetContainerId);

    var linkFunc = $compile(html);
    var content = linkFunc($scope);
    target.append(content);

    self.UpdateScreenBreadCrumb(viewIdentifier, breadCrumbContainerId);
}

此时我还需要测试实际的链接,但是这可以加载新的屏幕并折叠前一个。