【问题标题】:Unable to observe Bootstrap event in Aurelia custom attribute无法在 Aurelia 自定义属性中观察 Bootstrap 事件
【发布时间】:2017-05-01 11:16:40
【问题描述】:

我正在努力将名为 FullCalendar 的 JavaScript 事件日历合并到 Aurelia 应用程序中。我有一个名为dashboard 的标准Aurelia 模块,并将日历实现放入名为calendar.js 的单独.js 文件中,并创建了一个名为calendar 的自定义属性。我正在使用自定义属性,因为没有附加 calendar 视图,所有内容都是在 JavaScript 中生成的。

由于在页面加载时日历不可见(因为它不在主选项卡或活动选项卡上),因此在自定义属性代码中触发 attached() 方法时不会绘制它。我需要能够从自定义属性观察 Bootstrap 事件(单击选项卡),以便在最终单击选项卡时触发 .render 方法来绘制日历。

这是我的代码的相关sn-ps:

dashboard.html:

<!-- Standard Bootstrap tabs -->
<ul class="nav nav-tabs" role="tablist">
                    <li role="presentation" class="active"><a href="#tab1" role="tab" data-toggle="tab">Projects</a></li>
                    <li role="presentation"><a href="#tab2" role="tab" data-toggle="tab" id="calselect">Calendar</a></li>
                    ...
                    ...
<!-- and further down the same page, the tab panes with their content -->
<div class="tab-content">
    <div role="tabpanel" class="tab-pane active" id="tab1">
        <!-- Table content here... -->
    </div>
    <div role="tabpanel" class="tab-pane" id="tab2">
        <div class="row">
            <div class="col-md-12">
                <div class="panel panel-white">
                    <div class="panel-body">
                        <div calendar calvisible.bind="calVisible"></div>
                    </div>
                </div>
            </div>
        </div><!-- Row -->  
    </div>
</div>

dashboard.js:

...
  constructor(http, dataRepository) {
    this.http = http;
    dataRepository.getProjects().then(projects => this.projects = projects);
    this.calVisible = false;
  };
...
  attached(){
    var cal = document.getElementById('calselect');
      $(cal).on('shown.bs.tab', (e) => {
        this.calVisible = true;
      });
  };

calendar.js:

 @bindable calvisible;

当单击选项卡时,Bootstrap 会触发一个名为 'shown.bs.tab' 的事件。 id="calselect" 引用了正确的选项卡。单击选项卡时,绑定属性this.calVisible 设置为true。随后,calvisible 绑定到calendar.js 文件。

我可以确定两个问题。首先,从calendar.js的角度来看,calvisible直到tab被点击是不存在的,导致webpack报错但不会crash应用。我无法使用 if 声明来捕捉到这一点,我不知道为什么。

其次,当单击选项卡时,即使calvisible 的值在calendar.js 文件中显示true,它也不会触发我可以在那里观察到的更改事件,这就是我需要的触发.render 方法来绘制日历。我曾尝试在这里使用@observable,但也无法让它工作。正确的做法是什么?

解决办法——

以下是基于@Fabio Luz 答案的获奖代码:

bind(){
    this.calvisible = this.calvisible;
}

calvisibleChanged(){
    $(this.element).fullCalendar('render');
}

【问题讨论】:

    标签: twitter-bootstrap fullcalendar aurelia


    【解决方案1】:

    在这种情况下,我认为您应该使用自定义元素而不是自定义属性。为了解决缺少 view 的问题,Aurelia 为您提供了 @noView 装饰器,see the docs。您的代码将如下所示:

    import {noView} from 'aurelia-framework';
    
    @noView
    export class Calendar {
       @bindable calvisible;
    
       bind() {
         //do your js magic here
       }
    
       calvisibleChanged() {
       }
    }
    

    你可能仍然会遇到一些 js 问题。更新您的代码,看看会发生什么,告诉我发生了什么,我会尽力为您提供更多帮助。

    【讨论】:

    • 嗨@Fabio,成功了。我修改了原始问题以包含工作代码。谢谢!
    【解决方案2】:

    抱歉,无法评论。 (答案与之前来自 Fabio Luz 的答案相同,除了你的错字有一点额外)

    您的代码中有错字吗?我在您的 view 中看到您正在绑定到 calVisible 但它在 viewModel 中是 calvisible 如果是这样,请这样做

    @bindable calVisible; // this was calvisible
    

    在此之后,您可以简单地在您的 viewModel 中进行操作:

    // Note that this will be called after the value changed
    calVisibleChanged(newValue) {
        if (newValue) {
            // Do something when cal is shown
        } else {
    
        }
    }
    

    【讨论】:

    • 不是错字。 js文件中的名称是驼峰式的,模板中的名称(即绑定的版本)都是小写的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 2017-03-24
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    相关资源
    最近更新 更多