当该元素的值发生变化时,是否会自动重新执行从元素读取值的Meteor Helper?

时间:2015-09-30 17:07:46

标签: javascript jquery mongodb meteor meteor-helper

我需要首先使用值填充一组select元素,如下所示:

<select class="jobLoc" id="date1Shift1JobLoc1" name="date1Shift1JobLoc1">
  {{#each jobLocations}}
    <option value={{jl_jobloc}}>{{jl_jobloc}}</option>
  {{/each}}
</select>

...但是当另一个相关的select元素发生变化时,更新那些(用子集替换joblocs的初始超集)。

帮助器根据相关select元素的值返回一组Documents,类似这样(伪代码):

Template.tblScheduler.helpers({
  jobLocations: function() {
    var worker = $('#worker').val;
    if (worker == '') {
        return JobLocations.find(); // return all
    } else {
        return JobLocations.find({ jl_workerid: worker }); // a worker was selected; use it to return a subset
    }
  }
});

首次渲染模板时,&#34; date1Shift1JobLoc1Count&#34; select元素填充了所有joblocs;但是,如果选择了一个工人,则选择&#34; date1Shift1JobLoc1Count&#34;应该清除,然后用适当的子集替换。

问题是,这是否会自动生效,因为Meteor认为帮助者依赖于&#34;#worker&#34;选择元素?我希望如此......但期待我希望得到太多。如果我的怀疑是有根据的,我怎样才能让助手重新运行,并重新渲染模板?我是否需要从模板事件处理程序执行此操作,如下所示:

Template.tblScheduler.events({
    "change #worker": function (event) {
      // Is it possible to call the jobLocations helper from here?
   }
}); 

?或者我必须这样做&#34;手动&#34;从那里,像(伪代码):

Template.tblScheduler.events({
    "change #worker": function (event) {
        var worker = $('#worker').val;
        var arrayOfDocs = Meteor.call('getJobLocsForWorker(worker))');
        // assign the values in arrayOfDocs to the "date1Shift1JobLoc1" select element
     }
}); 

还是有另一种方式吗?

2 个答案:

答案 0 :(得分:3)

jQuery元素是非反应性数据源,因为helpers依赖于它,我相信你最好的选择是将这个值包装在ReactiveVar中:

// set Label1.AutoSize to False and Label1.Width to
// the max width your UI will accept the Label1 to be...

function WillFitInLabel(Label: TLabel; const S: String): Boolean;
var
  R: TRect;
  C: TCanvas;
  DC: HDC;
begin
  R := Rect(0, 0, Label.Width, 0);
  C := TCanvas.Create;
  try
    DC := GetDC(0);
    try
      C.Handle := DC;
      try
        C.Font := Label1.Font;
        Windows.DrawText(DC, PChar(S), Length(S), R, DT_SINGLELINE or DT_CALCRECT);
      finally
        C.Handle := 0;
      end;
    finally
      ReleaseDC(0, DC);
    end;
  finally
    C.Free;
  end;
  Result := (R.Width <= Label.Width);
end;

var
  Names: String;
begin
  Names := ...;
  if WillFitInLabel(Label1, Names) then
    Label1.Caption := Names
  else
    ...
end;

您可能希望_.debounce对您的var worker = new ReactiveVar('') Template.tblScheduler.helpers({ jobLocations : function() { var workerValue = worker.get() //<- Register the dependency //Your cursor logic here } }) Template.tblScheduler.events({ 'change #worker' : function() { worker.set($('#worker').val) } }) 事件进行处理,以便用户不会看到整个用户界面闪烁并在其输入的每个字母处更新。

答案 1 :(得分:3)

一种可能的解决方案是明确声明帮助程序取决于您的#worker选择器。您可以使用Dependency对象执行此操作。

var workerDep = new Deps.Dependency();

然后,使用此对象“标记”帮助程序,如下所示:

Template.tblScheduler.helpers({
  jobLocations: function() {
    workerDep.depend();                 // <-----------
    var worker = $('#worker').val;
    if (worker == '') {
        // ...

要触发显式依赖项,请使用:

Template.tblScheduler.events({
    "change #worker": function (event) {
     workerDep.changed();             // <-----------