链接函数不会被调用

时间:2016-07-17 13:43:34

标签: javascript angularjs typescript

我写了一个自定义指令。

我的问题是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>

2 个答案:

答案 0 :(得分:1)

分步教程&#39; 如何解决指令链接问题&#39;:

第1步 AngularJS是否有任何要显示的内容?  您必须检查对象是否包含页面上的数据

  • 检查&#39; 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; 的 示例:

  • name =&#39; data-kz-newegg-tab &#39;将是ngAttrName =&#39; kzNeweggTab &#39;
  • name =&#39; data-kz-new-egg-tab &#39;将是ngAttrName =&#39; kzNewEggTab &#39;

来源: From here:

Angular规范化元素的标记和属性名称,以确定哪些元素与哪些指令匹配。我们通常通过其区分大小写的camelCase规范化名称(例如ngModel)来引用指令。但是,由于HTML不区分大小写,我们通过小写形式引用DOM中的指令,通常使用DOM元素上的划线分隔属性(例如ng-model)。

规范化过程如下:

  1. 从元素/属性的前面剥离x-和数据。
  2. 将:, - 或_分隔的名称转换为camelCase ..
  3. 最后 如果您注意到AngularJS,保加利亚的一位开发人员Minko Gechev 'Build Your own Simplified AngularJS in 200 Lines of JavaScript会发表一篇好文章。在那里你可以熟悉基础知识 通过非常简单的代码了解AngularJS中指令的工作原理。

    祝你工作的项目好运。

答案 1 :(得分:0)

在您的代码中:

class Directive implements ng.IDirective

这是错误的。在没有new的情况下调用指令定义函数,因此class将不起作用。