类绑定在 emberjs 中不起作用,因为不检查属性

ClassBinding not working in emberjs as property is not checked

本文关键字:因为 不检查 属性 不起作用 绑定 emberjs      更新时间:2023-09-26

首先介绍一下背景,我正在构建一个事件列表系统,我想使用相同的模板列出事件,无论它们出现在何处,都可以来自搜索或作为页面上的小部件显示"即将发生"事件等。

因此,在搜索中,模板是这样呈现的

{{#each event in controller}}
    {{render 'event-item' event}}
{{/each}}

这让我使用这个模板

<div class="event" {{action 'showModal' this}}>
    {{#link-to 'details' this.id classNames="event__image" action="showModal" actionParam=this}}
        <img src="{{unbound this.EventLogoURL}}" />
    {{/link-to}}
    {{console-log this}}
    {{unbound AttractionName}}
    <h4 class="event__title">
        {{#link-to 'details' this.id action="showModal" actionParam=this}}
            {{unbound this.EventName}}
        {{/link-to}}
    </h4>
    <div class="event__info-links">
        <span class="event__more-info">{{#link-to 'details' this.id action="showModal" actionParam=this}}More Info{{/link-to}}</span> <span class="event__separator">|</span> <span class="event__book-now">{{#link-to 'details' this.id action="showModal" actionParam=this}}Book Now{{/link-to}}</span>
    </div>
    <button {{action 'toggleWishlist' this bubbles=false}} {{bind-attr class="isInWishlist:icon-star2:icon-star :add-to-wishlist"}}>
        {{#if isInWishlist}}
            Remove from wishlist
        {{else}}
            Add to wishlist
        {{/if}}
    </button>
</div>

我有一个事件的项目控制器,它是

import Ember from 'ember';
export default Ember.ObjectController.extend({
    needs: ['event/wishlist'],
    isInWishlist: function(){
        return this.get('controllers.event/wishlist').isInList(this.get('model'));
    }.property('controllers.event/wishlist.[]')
});

在搜索页面上,这一切都按预期工作,特别是InWishlist工作,现在,当我想将事件项模板用作小部件时,我创建了一个事件建议控制器和视图,这是在这样的页面上呈现

{{render 'event-suggestions' events type='startingToday'}}

这不会正确呈现,因为上下文不同,所以我不得不制作另一个模板并将this更改为 view.content 以输出正确的细节,所以我以这种方式渲染时使用的模板是

<div class="event" {{action 'showModal' view.content}}>
    {{#link-to 'details' view.content.id classNames="event__image" action="showModal" actionParam=view.content}}
        <img src="{{unbound view.content.EventLogoURL}}" />
    {{/link-to}}
    {{unbound view.content.AttractionName}}
    <h4 class="event__title">
        {{#link-to 'details' view.content.id action="showModal" actionParam=view.content}}
            {{unbound view.content.EventName}}
        {{/link-to}}
    </h4>
    {{!-- From: &pound;{{unbound view.content.PriceFrom}} --}}
    <div class="event__info-links">
        <span class="event__more-info">{{#link-to 'details' view.content.id action="showModal" actionParam=view.content}}More Info{{/link-to}}</span> <span class="event__separator">|</span> <span class="event__book-now">{{#link-to 'details' view.content.id action="showModal" actionParam=view.content}}Book Now{{/link-to}}</span>
    </div>
    <button {{action 'toggleWishlist' view.content bubbles=false}} {{bind-attr class="isInWishlist:icon-star2:icon-star :add-to-wishlist"}}>
        {{#if isInWishlist}}
            Remove from wishlist
        {{else}}
            Add to wishlist
        {{/if}}
    </button>
</div>

除了isInWishlist之外,这里的一切都有效(我可以将其切换入和调出愿望清单,这很好),但该功能从未在控制器中运行。

这是正在呈现的集合视图

import Ember from 'ember';
export default Ember.CollectionView.extend({
    classNames: ['slider'],
    parameters: {
        'DateFrom':            moment().format('DD/MM/YYYY'),
        'DateTo':              moment().format('DD/MM/YYYY'),
        'TimeFrom':            '10:00',
        'TimeTo':              '19:00',
        'Latitude':            BoxofficeENV.APP.defaultLatitude, // this.get('latitude'),
        'Longitude':           BoxofficeENV.APP.defaultLongitude, // this.get('longitude'),
        'SortOrderID':         1,
        'SortDirection':       0,
        'Pagesize':            18,
        'Pageno':              1,
        'DistinctAttractions': 1
    },
    content: null,
    type: null,
    contentBinding: 'controller',
    itemViewClass: 'event-suggestion-item',
    emptyView: Ember.View.extend({
        templateName: 'loading'
    }),
    didInsertElement: function() {
        console.log('suggestion area inserted');
    },
    setupParameters: function(){
        var type       = this.get('type'),
            property   = this.get('property'),
            params     = this.parameters
        ;
        // this is needed so we can cancel the request if it is made again before it finishes
        params.UID = type;
        this.send('prepareParams', params, type);
        this.get('controller').send('getEvents', params, type);
    }.on('didInsertElement'),
    updateOnLocationChange: function() {
        var type     = this.get('type'),
            property = this.get('property'),
            params     = this.parameters
        ;
        if (type === 'closeToYou') {
            // this is needed so we can canel the request if it is made again before it finishes
            params.UID = type;
            if(
                this.get('controller').get('location').latitude !== BoxofficeENV.APP.defaultLatitude &&
                this.get('controller').get('location').longitude !== BoxofficeENV.APP.defaultLongitude
            ) {
                params.Latitude  = this.get('controller').get('location').latitude;
                params.Longitude = this.get('controller').get('location').longitude;
                this.get('controller').send('getEvents', params, type);
            }
        }
    }.observes('controller.location'),

    actions: {
        prepareParams: function(params, type){
            switch(type) {
                case 'startingShortly':
                    var dateTimeFrom = moment();
                    var dateTimeTo   = moment();
                    dateTimeTo.add(7, 'day');
                    params.TimeFrom         = '00:00';
                    params.TimeTo           = '23:59';
                    params.DateFrom         = dateTimeFrom.format('DD/MM/YYYY');
                    params.DateTo           = dateTimeTo.format('DD/MM/YYYY');
                    params.MaxDistanceMiles = 10;
                    params.SortOrderID      = 5;
                    params.Latitude  = BoxofficeENV.APP.defaultLatitude;
                    params.Longitude = BoxofficeENV.APP.defaultLongitude;
                    break;
                case 'closeToYou':
                    params.TimeFrom         = '00:00';
                    params.TimeTo           = '23:59';
                    params.MaxDistanceMiles = 50;
                    if(
                        this.get('controller').get('location').latitude !== BoxofficeENV.APP.defaultLatitude &&
                        this.get('controller').get('location').longitude !== BoxofficeENV.APP.defaultLongitude
                    ) {
                        params.Latitude  = this.get('controller').get('location').latitude;
                        params.Longitude = this.get('controller').get('location').longitude;
                    }
                    break;
                case 'startingToday':
                    params.TimeFrom = moment().format('HH:mm');
                    var dateTime  = moment().add(7, 'day');
                    params.TimeTo = dateTime.format('HH:mm');
                    params.DateTo = dateTime.format('DD/MM/YYYY');
                    params.SortOrderID      = 6;
                    params.MaxDistanceMiles = 50;
                    break;
            }
        }
    }

});

这是阵列控制器

import Ember from 'ember';
export default Ember.ArrayController.extend({
    needs: ['application', 'event/wishlist'],
    itemController: 'event-item',
    location: function() {
        return this.get('controllers.application').get('location');
    }.property('controllers.application.location'),
    actions: {
        getEvents: function(params, property){
            var self = this;
            if (typeof this.store.adapterFor('event').xhrs[property] !== 'undefined'){
                this.store.adapterFor('event').xhrs[property].abort();
            }
            this.store.findQuery('event', params).then(function(data){
                self.set('model', data);
                Ember.run.scheduleOnce('afterRender', this, function(){
                    Ember.$('.'+property).find('.iosslider').iosSlider({
                        desktopClickDrag: true,
                        snapToChildren: true,
                        frictionCoefficient: 0.97
                    });
                });
            });
        }
    }
});

和事件项的两个视图文件

事件项.js

import Ember from 'ember';
export default Ember.View.extend({
    tagName: 'li',
    classNames: ['fadeInUp','animated','event-collection__event'],
    templateName: 'views/event-item'
});

事件建议项.js

import Ember from 'ember';
export default Ember.View.extend({
    tagName: 'div',
    classNames: ['slide'],
    templateName: 'views/event-suggestion-item'
});

如果我需要更具体,请告诉我。

我今天没有时间设置一个 jsfiddle 示例,但如果有帮助,我会看看明天是否可以设置一个。

我会将函数isInWishlist添加到您的itemViews中,因为这是模板的上下文。从那里,您应该有权访问控制器,因此它可以只是一个传递函数来调用控制器上的isInWishlist