Javascript强制重新计算对象属性的值

时间:2017-07-04 14:02:34

标签: javascript jquery

我想重新使用"对象"但是,每次访问对象时都应重新计算对象的一个​​属性值。

在我的代码中,我有一个库,基本上可以从数据网址列出卡片视图。此卡片视图列表将添加到页面中。有两种类型的列表:活动建筑物列表和存档建筑物列表。通过按下按钮来完成这两个列表之间的切换,这会触发"重新呈现"中继器的功能如下所示。

归档建筑物不应该是可点击的。我将一些配置选项传递给我的库,在那里我处理相关的部分。但是,由于我调用卡片视图库的方式,enableClick配置选项的值始终设置为页面加载时的状态。

代码的外观示例:

$(function () {
    var buildingsContainer = $('#buildings');
    buildingsContainer.repeater({
        url: function () {
            var activeFilter = buildingFilter.find('.btn-primary').data('status');
            return '/Building/All?status=' + activeFilter;
        },
        renderItem: cardTemplates(buildingsContainer).building({
            activateBuildingUrl: '@(Url.Action("ActivateBuilding", "Building"))/{Id}',
            editUrl: '@(Url.Action("Edit", "Building"))/{Id}',
            deleteBuildingUrl: '@(Url.Action("SoftDeleteBuilding", "Building"))/{Id}',
            enableClick: getActiveFilter() === 'Active'
        })
    })
});

function getActiveFilter() {
    var buildingFilter = $('#buildingFilter');
    return buildingFilter.find('.btn-primary').data('status');
}

无论当前按下的按钮是什么,enableClick始终设置为页面打开时的状态。

为了更好地展示我的问题,我创建了一个JSFiddle: https://jsfiddle.net/e3xnbxov/

在这个JSFiddle中,您看到我有一个options对象,其value属性。在按钮的单击侦听器中,我打印此值。但是,即使我在ActiveActive之间切换,它始终保持在Archived。我怎样才能重新计算属性的值?

3 个答案:

答案 0 :(得分:2)

我认为你有两个选择。

1)将属性设置为函数,并对其进行评估:

$(function() {
    var options = {
        value: ()=>$('#container').find('.btn-primary').data('status')
    };
    var container = $('#container');
    container.find('.btn').click(function() {
        container.find('.btn').removeClass('btn-primary').addClass('btn-default');
        $(this).addClass('btn-primary');
        console.log(options.value());
    });
});

jsfiddle:https://jsfiddle.net/mw8kuq6L/

2)只需使用“this”直接访问您要检查的数据值:

$(function() {
    var container = $('#container');
    container.find('.btn').click(function() {
        container.find('.btn').removeClass('btn-primary').addClass('btn-default');
        $(this).addClass('btn-primary');
        console.log($(this).data('status'));
    });
});

答案 1 :(得分:1)

问题是对象(options)创建一次,属性设置一次。

在创建(和属性设置)时,“active”按钮与jQuery选择器($('#container').find('.btn-primary'))匹配。

与许多语言一样,Javascript使用引用。设置对象的属性时,它会收到对jQuery选择器的结果的引用,而不是选择器(作为方法)本身。

您可以通过在对象上创建方法来将其更改为更符合您期望的行为:

$(function() {
    var options = {
        value: function () {
         return $('#container').find('.btn-primary').data('status')
      }
    };
    var container = $('#container');
    container.find('.btn').click(function() {
        container.find('.btn').removeClass('btn-primary').addClass('btn-default');
        $(this).addClass('btn-primary');
        console.log(options.value());
    });
});

因此,您的options对象现在有一个可调用的方法,可以动态返回您期望的内容。

否则,当所选按钮发生变化时,我更新属性:

$(function() {
    var options = {
        value: $('#container').find('.btn-primary').data('status')
    };
    var container = $('#container');
    container.find('.btn').click(function() {
        container.find('.btn').removeClass('btn-primary').addClass('btn-default');
        $(this).addClass('btn-primary');
    options.value = $('#container').find('.btn-primary').data('status');
        console.log(options.value);
    });
});

答案 2 :(得分:1)

这只是对lpg答案的补充。

另一种方法是使用getter函数,其行为类似于lpg的value函数,但可以像普通属性一样使用:

$(function() {
  var options = {
    // define a getter for the property 'value'
    get value () {
      return $('#container').find('.btn-primary').data('status');
    }
  };
  var container = $('#container');
  container.find('.btn').click(function() {
    container.find('.btn').removeClass('btn-primary').addClass('btn-default');
    $(this).addClass('btn-primary');
    console.log(options.value); // use the property for the property 'value'
  });
});
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<div id="container">
  <button class="btn btn-sm btn-primary" data-status="Active">Active</button>
  <button class="btn btn-sm btn-default" data-status="Archived">Archived</button>
</div>