我写了一个自定义指令。
我的问题是html模板永远不会呈现。
调试后我发现链接函数永远不会被调用,因为实例函数永远不会被调用。
我添加了“debugger;”
“调试器”;用//第一个注释来调用。所以我知道指令js文件加载了延迟加载。
这是我的指示:
module kz.controls.products.details {
'use strict';
debugger;//First
import IDropDown = kz.controls.common.IDropDown;
import FilterItemModel = WebApi.Core.Models.Common.FilterItemModel;
import NewEggTabModel = WebApi.Core.Models.Products.Details.NewEggTabModel;
import NewEggListingSettingsModel = Kyozou.Model.Auctions.NewEgg.NewEggListingSettings;
class TabController {
public $scope: ng.IScope;
public details: INewEggDetailsTab;
public errorsNotifyService: kz.blocks.IErrorsNotifyService;
public dropdownsDataService: kz.services.IDropdownsDataService;
public newEggListingSettingsService: kz.services.INewEggListingSettingsService;
public config: kz.settings.IApiEndpointConfig;
private formName: string;
private conditionNoteIsVisible: boolean;
private multiselectSettings = {
dynamicTitle: false,
showCheckAll: false,
showUncheckAll: false,
scrollableHeight: '200px',
scrollable: true,
};
private eventsFeedback = {
onItemSelect: () => {
},
onItemDeselect: () => {
}
};
private specificsPath: string[];
static $inject = [ "$modal", "$route"];
constructor(
private $modal,
private $route: ng.route.IRouteService
) { }
onDataLoaded() {
this.specificsPath = [this.config.getTypescriptPath('ts/controls/common/amazon-specifics.directive.js')];
this.$scope.$watch(() => {
return this.details.isDirty;
}, (newValue: boolean) => {
if (newValue) {
this.$scope['newEggTabForm'].$setDirty();
} else {
this.$scope['newEggTabForm'].$setPristine();
}
});
this.$scope.$watch(() => {
return this.$scope['newEggTabForm'] ? this.$scope['newEggTabForm']['$dirty'] : false;
}, (newValue: boolean, oldValue: boolean) => {
this.details.isDirty = newValue;
});
}
loadProductSettings(templateId: number, amazonSettingsID?: number): void {
}
setAmazonProductType(value: FilterItemModel) {
}
setAmazonProductConditionType(value: FilterItemModel) {
}
setStrategyType(value: FilterItemModel) {
}
setShipsDomestically(value: FilterItemModel) {
}
setFulfillmentChannel(value: FilterItemModel) {
}
setFulfillment(value: FilterItemModel) {
}
getKeysFromStringList(stringList: string[], dictionary: { [id: number]: { id; label; }; }): { id; }[] {
stringList = stringList || [];
var items: { id; }[] = [];
for (var key in dictionary) {
for (var i = 0; i < stringList.length; i++) {
if (dictionary[key].label === stringList[i]) {
items.push({ id: key });
continue;
}
}
}
return items;
}
getStringListFromKeys(keys: { id; }[], dictionary: { [id: number]: { id; label; }; }): string[] {
var items: string[] = [];
for (var i = 0; i < keys.length; i++) {
items.push(dictionary[keys[i].id].label);
}
return items;
}
updateAmazonSettings() {
this.details.isValid = this.$scope['newEggTabForm']['$valid'];
if (this.details.isDirty === false) {
this.errorsNotifyService.error('No changes!');
return;
}
angular.forEach(this.$scope['newEggTabForm'].$error.required, (field) => {
field.$setDirty();
});
this.$scope['newEggTabForm'].$setDirty();
if (this.details.isValid) {
}
}
searchCatalog(): void {
// this.details.searchCatalog(SearchCatalogTabEnum.Amazon, this.details.amazonListingSettingsModel.sellerId);
}
openLinkModal(): void {
//this.amazonCategoryService.getAmazonCategoryLink(this.details.amazonListingSettingsModel.templateId)
// .then(result => {
// this.amazonCategoryLink = result;
// this.modalInstance = this.$modal.open({
// templateUrl: this.config.getTemplatePath('ts/controls/common/amazon-category-link.modal.tpl.html'),
// scope: this.$scope,
// backdropClass: 'backdrop-fixed'
// })
// })
}
cancelModal(): void {
}
disable() {
}
enable() {
}
}
class Directive implements ng.IDirective {
restrict = 'EA';
controller = TabController;
controllerAs = 'vm';
replace = true;
templateUrl: string;
scope = {
details: '=',
};
constructor(errorsNotifyService, dropdownsDataService, newEggListingSettingsService, config: kz.settings.IApiEndpointConfig) {
debugger;
TabController.prototype.errorsNotifyService = errorsNotifyService;
TabController.prototype.dropdownsDataService = dropdownsDataService;
TabController.prototype.newEggListingSettingsService = newEggListingSettingsService;
TabController.prototype.config = config;
this.templateUrl = config.getTemplatePath('ts/controls/products/details/newEgg-tab.tpl.html');
}
link(scope: ng.IScope, element: ng.IAugmentedJQuery, attributes: ng.IAttributes,controller: TabController): void {
debugger;
controller.$scope = scope;
controller.details = scope['details'];
controller.onDataLoaded();
}
}
export interface INewEggDetailsTab extends kz.modules.products.details.IBaseTab {
productDetailsModel: WebApi.Core.Models.Products.ProductDetailsModel;
newEggListingSettingsModel: Kyozou.Model.Auctions.NewEgg.NewEggListingSettings;
newEggProductTypes: Array<FilterItemModel>;
newEggProductConditionTypes: Array<FilterItemModel>;
priceAdjustStrategyTypes: Array<FilterItemModel>;
newEggCategories: Array<FilterItemModel>;
newEggTabModel: NewEggTabModel;
enabled: boolean;
searchCatalog: (tab: SearchCatalogTabEnum, newEggSellerId: number) => void;
inTabView: boolean;
}
instance.$inject = [
kz.Constants.Services.ErrorsNotifyService,
kz.Constants.Services.DropdownsDataService,
kz.Constants.Services.NewEggListingSettingsService,
kz.Constants.Services.ApiEndPoint
];
function instance(errorsNotifyService, dropdownsDataService, newEggListingSettingsService, config): ng.IDirective {
debugger;
return new Directive(errorsNotifyService, dropdownsDataService, newEggListingSettingsService, config);
}
angular
.module(kz.Constants.Modules.ProductsDetailsControlls)
.directive(kz.Constants.Directives.NewEggTab, instance);
}
这是我的模板指令:
<form name="newEggTabForm" class="form-details">
<div block-ui="main">
<div loading-indicator>
<section class="form-horizontal form-details-section">
<header class="form-details-header">
<h4 class="title-sm">newegg</h4>
</header>
<div class="form-details-body">
<label class="spaced-right-inside-lg">
Enable or disable the newegg functionality for this product:
</label>
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="btn btn-default">Disabled</button>
<button type="button" class="btn btn-primary active">Enabled</button>
</div>
</div>
</section>
<section class="form-horizontal form-details-section">
<header class="form-details-header">
<h4 class="title-sm">newegg Marketplace Options</h4>
</header>
<div class="form-details-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="col-sm-3 col-md-4 control-label">newegg account:</label>
<div class="col-sm-9 col-md-8">
<div class="btn-group" dropdown>
<button type="button" class="btn btn-default dropdown-toggle" dropdown-toggle>
Choose <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="">NewEggTestSeller</a></li>
<li><a href="">NewEggTestSeller2</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 col-md-2 control-label">Industry and subcategory:</label>
<div class="col-sm-9 col-md-10">
<div class="btn-group" dropdown>
<button type="button" class="btn btn-default dropdown-toggle" dropdown-toggle>
Choose <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="">Accessories (1)</a></li>
<li><a href="">Apparel (62)</a></li>
</ul>
</div>
<div class="btn-group" dropdown>
<button type="button" class="btn btn-default dropdown-toggle" dropdown-toggle>
Choose <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="">Air Conditioners</a></li>
<li><a href="">Air purifier</a></li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="inputListingPrice" class="col-sm-3 col-md-4 control-label">newegg listing price:</label>
<div class="col-sm-9 col-md-8">
<input type="text" class="form-control input-number" id="inputListingPrice" name="inputListingPrice">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="inputSellerPart" class="col-sm-3 col-md-4 control-label">Seller part #:</label>
<div class="col-sm-9 col-md-8">
<input type="text" class="form-control" id="inputSellerPart" name="inputSellerPart">
</div>
</div>
<div class="form-group">
<label for="inputRelatedSellerPart" class="col-sm-3 col-md-4 control-label">Related seller part #:</label>
<div class="col-sm-9 col-md-8">
<input type="text" class="form-control" id="inputRelatedSellerPart" name="inputRelatedSellerPart">
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="customInput" class="col-sm-3 col-md-4 control-label">Condition:</label>
<div class="col-sm-9 col-md-8">
<label class="radio-inline">
<input type="radio" name="conditionRadios" checked=""> New
</label>
<label class="radio-inline">
<input type="radio" name="conditionRadios"> Refurbished
</label>
</div>
</div>
<div class="form-group">
<label for="customInput" class="col-sm-3 col-md-4 control-label">Item package:</label>
<div class="col-sm-9 col-md-8">
<label class="radio-inline">
<input type="radio" name="packageRadios" checked=""> Retail
</label>
<label class="radio-inline">
<input type="radio" name="packageRadios"> OEM
</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-4 col-sm-9 col-md-8">
<div class="checkbox">
<label>
<input type="checkbox"> Override product description
</label>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-3 col-md-2 control-label">
<label for="inputConditionNote">Product description:</label>
<div><i class="fa fa-arrows-h icon-success"></i> <span class="side-details text-sm text-details">max 4000 chars</span></div>
</div>
<div class="col-sm-9 col-md-10">
<textarea class="form-control" id="inputConditionNote" name="inputConditionNote" rows="5"></textarea>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="customInput" class="col-sm-3 col-md-4 control-label">Shipping:</label>
<div class="col-sm-9 col-md-8">
<label class="radio-inline">
<input type="radio" name="shippingRadios" checked=""> Default
</label>
<label class="radio-inline">
<input type="radio" name="shippingRadios"> Free
</label>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="form-horizontal form-details-section">
<header class="form-details-header">
<h4 class="title-sm">Hazards and restrictions</h4>
</header>
<div class="form-details-body">
<div class="form-group">
<label class="col-sm-3 col-md-2 control-label">Hazards and restrictions:</label>
<div class="col-sm-9 col-md-10">
<div class="form-group">
<label class="col-sm-3 col-md-4 control-label">Shipping hazardous materials:</label>
<div class="col-sm-9 col-md-8">
<label class="radio-inline">
<input type="radio" name="materialsRadios" checked=""> Yes
</label>
<label class="radio-inline">
<input type="radio" name="materialsRadios"> No
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 col-md-4 control-label">Age 18+ verification:</label>
<div class="col-sm-9 col-md-8">
<label class="radio-inline">
<input type="radio" name="ageRadios" checked=""> Yes
</label>
<label class="radio-inline">
<input type="radio" name="ageRadios"> No
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 col-md-4 control-label">Choking hazard:</label>
<div class="col-sm-9 col-md-8">
<div class="checkbox">
<label>
<input type="checkbox"> Item contains small parts.
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Item is a small ball.
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Item contains a small ball.
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Item contains balloons.
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Item is a marble.
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Hazards and restrictions
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 col-md-4 control-label">California proposition 65:</label>
<div class="col-sm-9 col-md-8">
<div class="radio">
<label>
<input type="radio" name="propositionRadios" checked=""> None
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="propositionRadios"> Item is a motherboard and contains chemicals know to the state California to cause cancer and reproductive toxicity.
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="propositionRadios"> Item is NOT a motherboard and contains chemicals know to the state California to cause cancer or reproductive toxicity.
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
<footer class="text-center">
<div loading-indicator-btn>
<button type="button" class="btn btn-secondary btn-wide text-semistrong"><span>Save</span></button>
</div>
</footer>
</div>
这是我使用指令的地方:
<div class="tab-content" ng-repeat="tab in vm.tabsVisibility.newEggTabs" ng-if="vm.selectedTab == 'newegg-'+tab.newEggSellerId">
<div oc-lazy-load="vm.lazyLoadParams">
<div data-kz-newegg-tab data-details="vm.newEggDetailsTabs['newegg-'+tab.newEggSellerId]"></div>
</div>
</div>
答案 0 :(得分:1)
分步教程&#39; 如何解决指令链接问题&#39;:
第1步。 AngularJS是否有任何要显示的内容? 您必须检查对象是否包含页面上的数据
vm.tabsVisibility.newEggTabs
&#39;有一些数据检查ng-if="vm.selectedTab == 'newegg-'+tab.newEggSellerId"
是否为&{39; true
&#39;
如果一切正常,请继续执行第2步
第2步。 AngularJS是否将我的属性识别为已编译指令的名称?
如果您的指令已在上面提到的运行时<div oc-lazy-load="vm.lazyLoadParams">
编译,那么您应该能够在AngularJS知道的指令数组中找到它。
我的指令的名称是什么? - 在指令名称规范化期间,AngularJS会找到您的attrubite并最终得到以下指令名称
ngAttrName = directiveNormalize(name);
name = 'data-kz-newegg-tab'
而不是ngAttrName = 'kzNeweggTab'
常数&#39; kz.Constants.Directives.NewEggTab
&#39;的值应该是kzNeweggTab
&#39;。
我猜错只是因为你没有分享这种代码的和平,但如果价值拼写错误或与AngularJS所期望的名称不同,那么链接&#39;功能永远不会被执行。
我在您的代码中看到有很多地方您使用&#39; NewEggTab&#39; 而不是 NeweggTab &#39; 的 示例: 强>
来源: From here:
Angular规范化元素的标记和属性名称,以确定哪些元素与哪些指令匹配。我们通常通过其区分大小写的camelCase规范化名称(例如ngModel)来引用指令。但是,由于HTML不区分大小写,我们通过小写形式引用DOM中的指令,通常使用DOM元素上的划线分隔属性(例如ng-model)。
规范化过程如下:
最后 如果您注意到AngularJS,保加利亚的一位开发人员Minko Gechev 'Build Your own Simplified AngularJS in 200 Lines of JavaScript会发表一篇好文章。在那里你可以熟悉基础知识 通过非常简单的代码了解AngularJS中指令的工作原理。
祝你工作的项目好运。
答案 1 :(得分:0)
在您的代码中:
class Directive implements ng.IDirective
这是错误的。在没有new
的情况下调用指令定义函数,因此class
将不起作用。