指令不更新控制器 属性
Directive not updating controller property
我编写了一个自定义指令来检测在文本框中按下的回车键。这是指令代码
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 版。
您的主要错误在于您传递指令的属性名称。
明确一点,如果你有 scope: {showAddTextbox: '=?'}
(camelCase) 你必须在 html 中传递 attr,比如 <input bookmark-enter show-add-textbox="$ctrl.showAddTextbox"
( 烤肉包).
当您引用指令参数时,还要在 link 函数中将 controller.
更改为 scope.
。
** 作为建议,您可以使用 $scope.applyAsync()
或 $timeout(function(){ //your code })
而不是 $scope.apply()
。这是为了防止出现 $digest already in progress
angularjs 错误。
示例:
HTML
<input type="text" bookmark-enter show-add-textbox="$ctrl.showAddTextbox" ng-model="$ctrl.newBookmarkTitle" ng-show="$ctrl.showAddTextbox"/>
指令
restrict: "A",
scope: {
showAddTextbox: "=?",
newBookmarkTitle: "=ngModel"
},
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", scope.newBookmarkTitle);
scope.$timeout(() => {
scope.showAddTextbox = false;
scope.newBookmarkTitle = "";
});
}
});
},
我编写了一个自定义指令来检测在文本框中按下的回车键。这是指令代码
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 版。
您的主要错误在于您传递指令的属性名称。
明确一点,如果你有 scope: {showAddTextbox: '=?'}
(camelCase) 你必须在 html 中传递 attr,比如 <input bookmark-enter show-add-textbox="$ctrl.showAddTextbox"
( 烤肉包).
当您引用指令参数时,还要在 link 函数中将 controller.
更改为 scope.
。
** 作为建议,您可以使用 $scope.applyAsync()
或 $timeout(function(){ //your code })
而不是 $scope.apply()
。这是为了防止出现 $digest already in progress
angularjs 错误。
示例:
HTML
<input type="text" bookmark-enter show-add-textbox="$ctrl.showAddTextbox" ng-model="$ctrl.newBookmarkTitle" ng-show="$ctrl.showAddTextbox"/>
指令
restrict: "A",
scope: {
showAddTextbox: "=?",
newBookmarkTitle: "=ngModel"
},
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", scope.newBookmarkTitle);
scope.$timeout(() => {
scope.showAddTextbox = false;
scope.newBookmarkTitle = "";
});
}
});
},