簡體   English   中英

如何在視圖中多次正確使用相同的AngularJS 1.5組件?

[英]How to properly use the same AngularJS 1.5 component multiple times in a view?

我正在使用AngularJS 1.5的新組件創建一組小部件。 問題是,當多次使用相同的小部件時,它們以某種方式共享其控制器或作用域。 我認為關於組件的一件事是它們的范圍是完全隔離的?


我的主要HTML模板包含小部件:

<widget-list
    title="Books"
    class="col-xs-12 col-md-4">
</widget-list>

<widget-list
    title="Movies"
    class="col-xs-12 col-md-4">
</widget-list>

<widget-list
    title="Albums"
    class="col-xs-12 col-md-4">
</widget-list>

我的小部件模板:

<div class="widget widget-list">
    <div class="panel b-a">

        <div class="panel-heading b-b b-light">
            <h5>{{$widget.title}}</h5>
            <div class="pull-right">
                <button type="button" class="btn btn-default btn-sm" ng-click="$widget.doSomething()">
                    Do something
                </button>
            </div>
        </div>

        <div class="panel-content">
            {{$widget.content || 'No content'}}
        </div>

    </div>
</div>

我的小部件組件:

app.component('widgetList', {
    templateUrl: 'template/widget/widget-list.html',
    bindings: {
        title   : '@',
    },
    controllerAs: '$widget',
    controller: function($timeout) {

        $widget = this;

        console.log('Title on init: ', $widget.title)

        $timeout(function() {
            console.log('Title after 3 seconds: ', $widget.title)
        }, 3000)

        $widget.doSomething = function() {
            $widget.content = "Something";
        }
    }
});

運行代碼時,控制台如下所示:

Title on init: Books
Title on init: Movies
Title on init: Albums
(3) Title after 3 seconds: Albums

同樣在渲染之后,所有三個小部件在其模板中均不顯示No content 但是,當單擊三個小部件之一中的doSomething()按鈕時,只有最后一個小部件的內容才會更新為Something

這是怎么回事 為什么我的組件沒有被“隔離”?

看起來您這里有一個名為$ widget的全局變量,請嘗試以下操作:

var $widget = this;

代替

$widget = this;

由於$ widget變量保存對最近初始化的控制器的引用,在本例中為對第三個組件的控制器的引用,因此會造成混亂。

您的代碼的問題是,您在窗口范圍內聲明了$widget ,這就是為什么您的控制器打印最后一個值的原因,因為每次實例化控制器時,它都會被覆蓋。 使用var $widget代替,您的代碼將正常工作。

以下代碼段解決了此問題:

 angular.module('app', []) .component('widgetList', { templateUrl: 'template/widget/widget-list.html', bindings: { title: '@', }, controllerAs: '$widget', controller: WidgetListController }); function WidgetListController($timeout) { var $widget = this; console.log('Title on init: ', $widget.title) $timeout(function() { console.log('Title after 3 seconds: ', $widget.title) }, 3000) $widget.doSomething = function() { $widget.content = "Something"; } } angular.element(document).ready(function() { angular.bootstrap(document, ['app']); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script> <widget-list title="Books" class="col-xs-12 col-md-4"> </widget-list> <widget-list title="Movies" class="col-xs-12 col-md-4"> </widget-list> <widget-list title="Albums" class="col-xs-12 col-md-4"> </widget-list> <script type="text/ng-template" id="template/widget/widget-list.html"> <div class="widget widget-list"> <div class="panel ba"> <div class="panel-heading bb b-light"> <h5>{{$widget.title}}</h5> <div class="pull-right"> <button type="button" class="btn btn-default btn-sm" ng-click="$widget.doSomething()"> Do something </button> </div> </div> <div class="panel-content"> {{$widget.content || 'No content'}} </div> </div> </div> </script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM