嵌套的view-model.ref

时间:2016-04-22 19:23:12

标签: aurelia

我们有一个页面“parent”,它通过parent.html中名为“child”的view-model.ref引用模板。我们通过单击父页面上使用OpenDetailsDiv调用子函数的项来更改此子模板的数据。假设我为此事件使用了一个按钮,如下所示:

parent.html

<child view-model.ref="clientusertasks"></child>
<input type="button" value="Click Me" click.trigger="OpenDetailsDiv" />

通过这种方式,我们可以从父视图模型调用“子”视图模型上的函数,如下所示:

parent.js

import { inject } from 'aurelia-framework';
import { HttpClient } from 'aurelia-fetch-client';
import 'fetch';
import AuthService from 'AuthService';
import { BpoClientUserTasks } from './bpo-client-user-tasks';

@inject(HttpClient, AuthService, BpoClientUserTasks)
export class Parent {
  smallDivObj = {};
  freq = '';
  period = '';
  filterVal = '';
  client = '';

  constructor(http, AuthService, BpoClientUserTasks) {

    http.configure(config => {
      config
        .withBaseUrl("WebServices.asmx/")
        .withDefaults({
          headers: {
            'Accept': 'application/json'
          }
        });
    });

    this.http = http;
    this.auth = AuthService;
    this.clientusertasks = BpoClientUserTasks;
  }


  OpenDetailsDiv(myObject) {
    this.clientusertasks.CallBPOClientUserService(this.freq, this.period, this.filterVal, myObject.TrueClient, myObject.Client);
  }
}

到目前为止一切顺利。 “child”视图模型具有此函数CallBPOClientUserService,如下所示:

child.js

import { inject } from 'aurelia-framework';
import { HttpClient } from 'aurelia-fetch-client';
import 'fetch';
import AuthService from 'AuthService';

@inject(HttpClient, AuthService)
export class Child {
  smallDivObj = {};

  constructor(http, AuthService) {

    http.configure(config => {
      config
        .withBaseUrl("WebServices.asmx/")
        .withDefaults({
          headers: {
            'Accept': 'application/json'
          }
        });
    });

    this.http = http;
    this.auth = AuthService;
  }

  attached() {

  }

  CallBPOClientUserService(freq, period, filterVal, client, displayClient) {
    $('#TasksByClientByUserDiv').addClass("fade");

    this.freq = freq;
    this.period = period;
    this.filterVal = filterVal;
    this.client = client;

    var mymethod = {
      method: 'post',
      body: JSON.stringify({
        "session": this.auth.session,
        "Client": client,
        "FreqFilter": freq,
        "FilterVal": filterVal
      }),
      headers: {
        'content-type': 'application/json'
      }
    };
    //alert(JSON.stringify(mymethod));
    this.http.fetch('GetBPOTasksByClientByUserDiv', mymethod)
      .then(response => response.json())
      .then(info => {
        this.tasksByClientByUser = JSON.parse(info.d);

        //setTimeout("$('#TasksByClientByUserTable').tablesorter();", 100);  
      });
  }
}

请注意,在函数CallBPOClientUserService中,我们希望调用一个tablesorter排序函数,以便在呈现DOM之后对视图中的表进行排序。

通常我会在视图模型的“附加”组件生命周期中调用此函数。但是你可以看到我们填充这个视图的方式是来自“父”页面的view-model.ref,它使得“child”的“附加”组件在这种情况下无用(它只被调用一次)当父母被加载时)。

所以我的问题:

我是否有一个等效的attached组件来调用这个tablesorter函数?

我有一个便宜的解决方法,我可以使用我在函数中评论的setTimeout,但我宁愿在Aurelia事件中正确执行此操作,并保证DOM已完成。< / p>

1 个答案:

答案 0 :(得分:0)

我相信我有两个解决这个问题的方法,我很满意并会在这里发布。

首先是Fabio上面推荐使用 microTaskQueue

另一个解决方案是使用自定义可绑定事件在完成此处的表上的repeat.for时调用该函数...

<template>
<require from='../tablesorter-bind'></require>

<section id="TasksByClientDiv" class="SmallDivPanel ui-draggable BIBulletinSection100 SmallDivSection hellfire">
    <small-div-header smalldivinfo.bind="smallDivObj"></small-div-header>

    <div id="TasksByClientBox">
        <div style="margin-top: 10px;font-size: 20px;">Frequency: ${freq} / Period: ${filterVal}</div>

        <div id="TasksByClientTableDiv" class="SmallDivMainPanel">
            <table id="TasksByClientTable" >
                <thead class="tablesorter">
                    <tr>
                        <th>Client</th>
                        <th>Received</th>
                        <th>Prepped</th>
                        <th>Loaded</th>
                        <th>Doc Loaded</th>
                    </tr>
                </thead>

                <tbody>
                    <tr click.trigger="OpenDetailsDiv(x)" repeat.for="x of tasksByClient" table-id.bind="tableId">
                        <td>${x.Client}</td>
                        <td>${x.totLoaded}</td>
                        <td>${x.totLoaded}</td>
                        <td>${x.totPrepped}</td>
                        <td>${x.numDocLoaded}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</section>
</template>

其中tableId在View-Model中定义为我的tableID

然后我像这样设置自定义元素:

的tablesorter-bind.js

import {inject, customAttribute, TaskQueue} from 'aurelia-framework';

@customAttribute('table-id')
@inject(Element, TaskQueue)
export class TablesorterBind {
constructor(element, taskQueue) {
    // "element" will be the DOM element rendered from the template     
    this.element = element;
    this.taskQueue = taskQueue;
}    

attached() {

}

bind(bindingContext, overridingContext) {
    if (overridingContext.$last === true) {
        this.taskQueue.queueMicroTask(
            () => {
                //This is the jQuery update call to the tablesorter function
                $('#' + this.value).trigger('update');
            }
        );
    }
}

}