匿名函数时发布更新 DTM 预定义数据元素

Issue Updating DTM Pre-defined Data Element when Anonymous FUnction

如果我有一个名为 "CS Test" 的预定义数据元素:

return (function() { 
  var rvalue = "default custom script value from some data layer";
  return rvalue;
})();

我想根据基于事件的规则用新值(例如 "Updated Value")更新 "CS Test" 数据元素的值。我不能让它工作?我从之前的 post 了解到,当您显式调用 _satellite.getVar('Example') 时,操作顺序改为:

  1. 查找类型的指定目标(例如 JS 对象类型的路径 (js var))和 return 该值
  2. 寻找卫星 cookie 和return那个值
  3. Return默认值

所以不确定如何解决这个问题,因为数据元素代码总是被执行并且 return 正在输入一个值?

My point above is that updating the satellite cookie works but only until I call the last _satellite.getVar("CS Test") because it overwrites the satellite cookie with the value of the Data element code and returns the value of the Data Element.

好吧,我将在这里提出几个不同的想法,因为您还不清楚数据元素功能的真正作用、您总体上想要实现的目标等等。所以也许其中的一些内容既能阐明 DTM 的工作原理,又能帮助您到达目的地。

仅直接设置数据元素的 cookie "works" 以便在 DTM 内部引用它时更新它,例如(如前所述)后续页面加载。此外,我认为(但尚未测试)在规则字段中使用 %data_element% 语法时它会起作用。

但是,相同 link 我在 OP 评论 中发帖),当您显式调用 _satellite.getVar() 时,它会强制执行要评估的数据元素规则。这意味着你在那里的代码(你的匿名函数)将被执行,并做它做的任何事情。

而且 听起来 可能您希望 DTM 以某种方式执行它,但有选择地忽略其中的一些。嗯,这对 DTM 来说是不可能的。如果你想要这样的事情发生,那么你必须重写你的匿名函数来适应做这样的事情。但我稍后会回到这个问题上,因为首先我想退后一步问..

你为什么还要在写完 cookie 后立即使用 _satellite.getVar()?直接写入 cookie 的要点是您 绕过 数据元素。更重要的是,你已经有了这个值,因为你只是用它设置了 cookie

因此,也许您只是为了示例而合并了您的代码,而随后的 .getVar() 调用位于单独的代码框中,或者在您设置 cookie 的范围之外。

如前所述,当您显式调用 .getVar() 时,DTM 对 return 值的操作顺序是

  1. 评估数据元素。这意味着您的匿名函数将 执行。如果这个 return 是一个真值,那就是你得到的。如果它 return 不是真实值..

  2. 如果它是持久数据元素,DTM 会查找 _sdsat_[data element name] cookie。如果它存在(并且有真值),那就是 你得到什么。如果没有,那么..

  3. Return 你在数据中指定为默认值的值 元素配置(如果您未指定任何内容,则为未定义)

再一次,我有点摸不着头脑,因为我不知道你的数据元素的细节和它的最终目标,但在我看来你希望能够调用 .getVar() 但操作顺序与 DTM 在页面加载时的操作顺序相同(1 和 2 颠倒)。好吧,DTM 没有内置的方法来执行此操作。如果 Adob​​e 在数据元素配置中添加选项以指定操作顺序,那就太好了,因为显然它的行为不同,具体取决于数据元素的引用方式(由 DTM 本身或您引用)。但他们目前没有。

因此,如果这是您想要的,那么您需要重构您的匿名函数,使其表现得更像 DTM 对持久数据层的表现。基本上,向其中添加代码以查找默认值为 rvalue 的 cookie, 然后 返回到您现在拥有的值。这应该允许您显式调用 .getVar(),因为现在首先执行的匿名函数将首先查找 cookie 值。

另一种选择可能是..假设所有这些代码(即麻烦的后续 .getVar() 调用)都在同一规则内,但无论出于何种原因都在您设置 cookie 的范围之外首先(例如,在单独的代码框中),您可以将值设置为不同的、即时创建的数据元素,然后引用它。这样做而不是仅仅读取 cookie 的好处是它将它暴露给一个数据元素,这样你也可以使用 %data_element% 语法(从你设置它的地方,向前移动)如果你需要.

更新:

好的,从后续评论来看,我正在玩 DTM,看起来您可以执行以下操作,这可能正是您要找的。

页面范围持久化

因此,例如在预定义的数据元素中,您可以有这样的内容:

return function(rvalue) { 
  _satellite.data.customVars._defaultRvalue = 
    rvalue
    ||
    _satellite.data.customVars._defaultRvalue
    ||
    "default custom script value from some data layer"
  ;
  return _satellite.data.customVars._defaultRvalue;
}

然后,要获取当前值,您可以这样做:

_satellite.getVar('data_element')();

这将 return 当前值或 "default[..]" 如果有 none。

然后,如果你想设置一个新的值,你可以这样做:

_satellite.getVar('data_element')('new value');

这将 return "new value",如果您进行后续调用(页面范围):

_satellite.getVar('data_element')();

会继续return"new value"。

示例场景:

_satellite.getVar('data_element')(); // initial page load, returns "default[..]"
_satellite.getVar('data_element')('foo'); // returns 'foo'
_satellite.getVar('data_element')(); // returns 'foo'
_satellite.getVar('data_element')('bar'); // returns 'bar'
_satellite.getVar('data_element')(); // returns 'bar'

注意:这仅适用于页面持续时间。如果您需要它在页面之间持续存在,则需要改为设置并从 cookie 中提取。不要使用 _sdsat_[data_element] cookie,因为函数本身存储在 cookie 中。

Session+持久化(从页面加载持续到页面加载)

因此,要在整个会话中从一个页面到另一个页面持久保存它,例如,您可以这样做:

return function(rvalue) { 
  var rvalue=
    rvalue
    ||
    _satellite.readCookie('rvalue')
    ||  
    "default custom script value from some data layer"
  ;
  _satellite.setCookie('rvalue',rvalue);
  return _satellite.readCookie('rvalue');
}

示例场景:

_satellite.getVar('data_element')(); // initial page load, returns "default[..]"
_satellite.getVar('data_element')('foo'); // still on same page, returns 'foo'
_satellite.getVar('data_element')(); // still on same page, returns 'foo'
// reload page or go to new page:
_satellite.getVar('data_element')(); // new page: returns 'foo'
_satellite.getVar('data_element')('bar'); // returns 'bar'
// reload page or go to new page:
_satellite.getVar('data_element')(); // new page: returns 'bar'

注意: 这样做的一个主要警告是,因为您实际上是在使 .setVar 方法成为函数的包装器,所以您将无法引用它在具有 %data_element% 语法的规则的表单字段中。嗯,你 可以 ,但它不会给你你想要的。在我的测试中,它 return 是函数本身的字符串化版本,但谁知道它还会如何反应,具体取决于 browser/version。只是不要这样做。