简体   繁体   English

将Angular与MVC部分视图混合

[英]Mixing Angular with MVC partial views

What I need 我需要的

A chain of screens that each open the next screen on a button click. 一系列屏幕,每个屏幕单击一次即可打开下一个屏幕。 Each previous screen must be collapsed and the new screen must be added by loading a partial view from the MVC backend. 每个先前的屏幕都必须折叠,并且必须通过从MVC后端加载部分视图来添加新屏幕。

What I have 我有的

An AngularJS controller with the following function: 具有以下功能的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);
        });
    };
}

The UpdateScreenBreadCrumb function works and is otherwise unrelated. UpdateScreenBreadCrumb函数有效,否则不相关。

It is called (for instance) like this: 它被称为(例如)如下:

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

What it does 它能做什么

The content of the View, a form, is loaded, the breadcrumb is updated correctly. 视图的内容(窗体)已加载,面包屑已正确更新。

What I need fixed 我需要解决的问题

On the partial view that was loaded, there is a button defined like this: 在已加载的局部视图上,有一个定义如下的按钮:

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

Clicking that button has no effect whatsoever. 单击该按钮没有任何作用。 If I add a console.log('Code was here.') to the AddPartialView(), it is not logged. 如果我将console.log('代码在这里。')添加到AddPartialView(),则不会记录它。 Setting the ng-click value directly to alert('hello') has no effect either. 将ng-click值直接设置为alert('hello')也不起作用。

There are no errors of any kind visible. 没有任何可见的错误。

Any suggestions on how to make this button work? 关于如何使此按钮起作用的任何建议?

In regards to your question, you are adding HTML that isn't compiled by Angular. 关于您的问题,您要添加的不是Angular编译的HTML。 You need to use $compile on your newly added HTML element and then bind it to a scope. 您需要在新添加的HTML元素上使用$ compile,然后将其绑定到作用域。 The $compile() function returns a link() function which you use to bind a scope to. $ compile()函数返回一个link()函数,您可以使用该函数将作用域绑定到该函数。 Example: 例:

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

NOTE : You should not be manipulating the DOM via a controller. 注意 :您不应该通过控制器来操作DOM。 This is considered bad practice. 这被认为是不良做法。 You should be using a custom directive or some combo of Angular directives (ngIf, ngSwitch, ngInclude). 您应该使用自定义指令或Angular指令的某些组合(ngIf,ngSwitch,ngInclude)。 I recommend watching AngularJS best practices . 我建议观看AngularJS最佳实践

I've looked into $compile, as suggested by Itamar L. and got it to work. 根据Itamar L.的建议,我研究了$ compile并使其起作用。 The samples I found were using Directives as well, so I implemented them anyway: 我发现的示例也使用了指令,因此无论如何我都实现了它们:

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);
                    }
                });
            }
        }
    }
]);

I use it like this: 我这样使用它:

<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>

That in itself displays the first page, which has a button to the next, as mentioned. 如前所述,它本身会显示第一页,其中的下一页具有按钮。 The associated function, found in the collapseController, is this: 在crashController中找到的关联函数是这样的:

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

The code for AddChildByDirective: 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);
}

At this point I still need to test actual chaining, but this works to load a new screen and collapse the previous. 在这一点上,我仍然需要测试实际的链接,但这可以加载新屏幕并折叠前一个屏幕。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM