指令不更新控制器属性

时间:2017-10-16 19:38:31

标签: angularjs typescript angularjs-directive

我编写了一个自定义指令来检测在文本框中按下的回车键。这是指令代码

import { BookmarkService } from "../services/bookmarkService";
import { qlik, QlikBookmarkInfo } from "../qlikInit";

class BookmarkListController {
/**
 * Injection parameters
 */
public static $inject: string[] = ["$scope", "bookmarkSvc"];

private $scope: ng.IScope;
private bookmarkSvc: BookmarkService;
private bookmark: QlikBookmarkInfo;
private bookmarkIndex: number;
private showToolbar: boolean = false;
public showAddTextbox: boolean = false;
public newBookmarkTitle: string = "";
private showEditBookmark: boolean = false;

public constructor(scope: ng.IScope, bookmarkSvc: BookmarkService) {
    this.$scope = scope;
    this.bookmarkSvc = bookmarkSvc;
}

public applyBookmark(bookmarkId: string, bookmarkTitle: string, bookmarkDescription: string): void {
    this.bookmark = {Id: "", Title: "", Description: ""};
    this.bookmark.Id = bookmarkId;
    this.bookmark.Title = bookmarkTitle;
    this.bookmark.Description = bookmarkDescription;
    this.showToolbar = true;
    qlik.applyBookmark("ABC", bookmarkId);
}

public createBookmark(): void {
    this.showAddTextbox = true;
}

public removeBookmark(): void {
    qlik.removeBookmark("ABC", this.bookmark.Id);
    this.bookmarkIndex = this.bookmarkSvc.bookmarksInfo.indexOf(this.bookmark);
    this.bookmarkSvc.bookmarksInfo.splice(this.bookmarkIndex, 1);
    this.showToolbar = false;
}

public editBookmark(): void {
    this.showEditBookmark = true;
    // do something
}

/* tslint:disable:no-any */
public saveBookmark(e: any): void {
    if (e.keyCode === 13) {
        qlik.createBookmark("ABC", this.newBookmarkTitle);
        this.showAddTextbox = false;
        this.newBookmarkTitle = "";
    }
}
/* tslint:enable:no-any */
}

export class BookmarkListComponent implements ng.IComponentOptions {
public templateUrl: string = "bookmarkList.html";
public controller: Function = BookmarkListController;
}

export function bookmarkEnter(): ng.IDirective {
return<ng.IDirective>{
    restrict: "A",
    scope: {
        showAddTextbox: "=?",
        newBookmarkTitle: "=?"
    },
    link: (scope: ng.IScope, element: ng.IAugmentedJQuery, attributes: ng.IAttributes, controller: BookmarkListController): void => {
        element.on("keyup", (e: any): void => {
            if (e.keyCode === 13) {
                qlik.createBookmark("ABC", controller.newBookmarkTitle);
                scope.$apply((): void => {
                    controller.showAddTextbox = false;
                    controller.newBookmarkTitle = "";
                });
            }
        });
    },
    controller: BookmarkListController,
    controllerAs: "$ctrlblc",
    bindToController: true
};
}

我在bookmarkList.html文件中使用如下指令

<div class="dsh-ListTitle">
<h4 class="dsh-ListTitle-title">Bookmarks</h4>
<a class="dsh-List-item" ng-click="$ctrl.createBookmark()">
    <ers-icon name="add" ers-tooltip="Add Bookmark"></ers-icon>
</a>
</div>
<div class="u-flex dsh-List dsh-List-icon" ng-show="$ctrl.showToolbar">
<a class="dsh-List-item" ng-click="$ctrl.editBookmark()">
    <ers-icon name="edit" ers-tooltip="Edit Bookmark"></ers-icon>
</a>
<a class="dsh-List-item" ng-click="$ctrl.removeBookmark()">
    <ers-icon name="delete" ers-tooltip="Delete Bookmark"></ers-icon>
</a>    
</div>
<ul class="dsh-List">
<li class="dsh-List-item" ng-repeat="bookmark in $ctrl.bookmarkSvc.bookmarksInfo">
    <a ng-click="$ctrl.applyBookmark(bookmark.Id, bookmark.Title, bookmark.Description)">{{bookmark.Title}}</a>
</li>
<li class="dsh-List-item" ng-show="$ctrl.showAddTextbox">
    <input type="text" bookmark-enter showAddTextbox="$ctrl.showAddTextbox" newBookmarkTitle="$ctrl.newBookmarkTitle" ng-show="$ctrl.showAddTextbox"/>        
</li>
</ul>

我想我已正确连接所有内容。在qlik.createBookmark()行,controller.newBookmarkTitle没有在文本框中输入文字。它以空字符串形式出现。如果我评估element.val(),则会在文本框中输入文字。

我在这里缺少什么?正在使用AngularJS 1.5版。

1 个答案:

答案 0 :(得分:3)

您的主要错误是您传递指令的属性名称。
要明确的是,如果你有scope: {showAddTextbox: '=?'} camelCase ),你必须传递html中的attr <input bookmark-enter show-add-textbox="$ctrl.showAddTextbox" kebab-case )。
当您引用指令参数时,还要在链接函数中更改controller.的{​​{1}}。

** 作为建议,您可以使用scope.$scope.apply()代替$scope.applyAsync()。这是因为你得到$timeout(function(){ //your code }) angularjs错误。

示例:

<强> HTML

$digest already in progress

<强>指令

<input type="text" bookmark-enter show-add-textbox="$ctrl.showAddTextbox" ng-model="$ctrl.newBookmarkTitle" ng-show="$ctrl.showAddTextbox"/>