Angular 1.5组件通过Ngroute更新父控制器



我正在使用ngroute创建一个角度单页应用程序。想要移至基于组件的版本。

问题是孤立的范围。我需要访问主控制器道具和方法。尝试使用绑定,但行不通。我找不到这个问题。该应用程序不使用组件就可以正常工作。当我尝试将主页视图更改为崩溃的组件时。这些是代码的主要部分:

框架

<html ng-app="angularModule" >
<body ng-controller="angularController as angCtrl" >
    <div ng-show="angCtrl.user.isLoggedIn" >Sign Out</div>
    <div ng-hide="angCtrl.user.isLoggedIn" cd-visible="angCtrl.showSignIn">Sign In</div>
    <div id="contentLayer" class="contentLayer" ng-view ></div>

主页模板

<h1 class="pageLabel" >HomePage</h1>
<blockquote>This can be anything. No bindings.</blockquote>

angularController

var app = angular.module ('angularModule', ['ngRoute'] );
app.directive ('cdVisible', 
    function () {
        return  function (scope, element, attr) {
                    scope.$watch (attr.cdVisible, 
                        function (visible) {
                            element.css ('visibility', visible ? 'visible' : 'hidden');
                        }
                    );
                };
    }
);
app.config ( [ '$locationProvider', '$routeProvider',
    function config ($locationProvider, $routeProvider) {
        $locationProvider.hashPrefix ('!');
        $routeProvider
        .when ('/sign-in', {
            templateUrl:    '/ng-sign-in',
            controller:     signInController
        })
        ... more routes
        .when ('/home', {
            template:   '<home-page showSignIn="angCtrl.showSignIn" menuSelect="angCtrl.menuSelect" ></home-page>'
        })
        .otherwise ('/home');
    }
]);
function homePageController () {
    this.menuSelect ('Devices');  // this statement has no effect on angularController.menuSelection chrome shows it as an anonymous function
    this.showSignIn = false;  // this bombs: Expression 'undefined' in attribute 'showSignIn' used with directive 'homepage' is non-assignable!
}
app.component ('homePage', {
    templateUrl:    '/ng-homepage',
    controller:     homePageController,
    bindings: {
        menuSelect: '&',
        showSignIn: '='
    }
});
app.controller ('angularController', [ '$http', '$window', '$location',
    function ($http, $window, $location) {
        var self = this; 
        this.user = {
            "isLoggedIn":       false
        };
        this.showSignIn = true;
        this.menuSelection = "";
        this.errorMessage = "";
        this.menuSelect = 
            function (selection) {
                self.menuSelection = selection;
            };
        this.setUserData =
            function (userData) {
                self.user = userData;
            };
        this.setShowSignIn =
            function (show) {
                self.showSignIn = show;
            };
        this.menuSelect ('');
        this.getUserData();     // I removed this for this post
    }
]);

我在引发异常的位置添加了评论。主页控制器试图更新AngularController的模型。第一个对第二次抛出异常无济于事。我究竟做错了什么?

首先, showSignIn是原始的,因此,角将其处理与执行showSignIn="7+2"完全相同的方式。如果您需要在组件内修改该值,则应将对象与showSignIn属性一起使用。

现在menuSelect有点艰难,也许Chrome Console显示了

之类的东西
function (locals) {
    return parentGet(scope, locals);
} 

这是因为您只是将对angCtrl.menuSelect的引用传递给组件。

为了从homePageController内部执行menuSelect函数(在HTML中):

<home-page menu-select="angCtrl.menuSelect(myMsg)"></home-page>

,然后在组件的控制器中这样称呼:

this.menuSelect({ myMsg:"Devices" })

HTML中的(myMsg)是呼叫Angular返回此引用的呼吁,然后在执行中,我们通过参数{ myMsg:"Devices" }以匹配我们刚才所做的参数。您可以检查此答案,以说明它更详细。

在阅读答案的过程中 - 最初编码的库库。

您的建议都起作用。谢谢。没有组件,我使用原型继承来访问父范围中的属性和方法。由于JavaScript原型继承的性质,修改父范围中标量的唯一方法是在父范围上调用Setter方法。显然,这里有类似的东西。有关JavaScript中原型继承的更多信息。

这是概念验证练习。我想测试我从组件中更新父范围中属性和对象的能力,并在父范围内执行方法。此示例以父范围更新标量2种不同的方式:

  1. 将其粘在对象中,绑定到对象,然后使用该对象从组件中使用该对象进行引用,例如使用logindata.showsignin boolean
  2. 在父范围内构建一个设置器方法并将其绑定到该方法,并从组件中调用setter,就像使用菜单选择一样(实际上无非是菜单选择的设置器)

并在此过程中演示调用功能。

最终工作代码是:(主页模板不更改)

框架

<html ng-app="angularModule" >
<body ng-controller="angularController as angCtrl" >
    <div ng-show="angCtrl.user.isLoggedIn" >Sign Out</div>
    <div ng-hide="angCtrl.user.isLoggedIn" cd-visible="angCtrl.loginData.showSignIn">Sign In</div>
    <div id="contentLayer" class="contentLayer" ng-view ></div>

angularController

var app = angular.module ('angularModule', ['ngRoute'] );
app.directive ('cdVisible', 
    function () {
        return  function (scope, element, attr) {
                    scope.$watch (attr.cdVisible, 
                        function (visible) {
                            element.css ('visibility', visible ? 'visible' : 'hidden');
                        }
                    );
                };
    }
);
app.config ( [ '$locationProvider', '$routeProvider',
    function config ($locationProvider, $routeProvider) {
        $locationProvider.hashPrefix ('!');
        $routeProvider
            .when ('/sign-in', {
                templateUrl:    '/ng-sign-in',
                controller:     signInController
            })
                ... more routes
            .when ('/home', {
                template:   '<home-page login-data="angCtrl.loginData" menu-select="angCtrl.menuSelect(mySelection)" ></home-page>'
            })
            .otherwise ('/home');
        }
]);
function homePageController () {
    this.menuSelect (   {   mySelection:    'Overview' });
    this.loginData.showSignIn = true;
}
app.component ('homePage', {
    templateUrl:    '/ng-homepage',
    controller:     homePageController,
    restrict:       'E',
    bindings: {
        menuSelect: '&',
        loginData:  '='
    }
});
app.controller ('angularController', [ '$http', '$window', '$location',
    function ($http, $window, $location) {
        var self = this; 
        this.user = {
            "isLoggedIn":       false
        };
        this.loginData = {
            "showSignIn":       false
        };
        this.menuSelection = "";
        this.errorMessage = "";
        this.menuSelect = 
            function (selection) {
                self.menuSelection = selection;
            };
        this.setUserData =
            function (userData) {
                self.user = userData;
            };
        this.setShowSignIn =
            function (show) {
                self.showSignIn = show;
            };
        this.menuSelect ('');
        this.getUserData();     // I removed this for this post
    }
]);

相关内容

  • 没有找到相关文章

最新更新