JavaScript : 每次我更新一些值时如何 return 一个函数?
JavaScript : How to return a function every time I update some value?
好吧,这个问题可能看起来有点抽象,但让我说得更清楚一点。这是关于我试图使用名为 Chartist 的图表库解决的问题。他们有一个称为插件的系统,您可以在其中为图表添加一些附加功能。现在解释如何编写插件here and at the bottom of this page。
现在我创建了一个 plunker 来演示这个问题...我面临的问题是每当我单击下拉菜单时,axisTitle 中的值永远不会改变...
你可能会问为什么?
原因是这几行 chartist-plugin-axistitle.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], function () {
return (root.returnExportsGlobal = factory());
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// like Node.
module.exports = factory();
} else {
root['Chartist.plugins.ctAxisTitle'] = factory();
}
}(this, function () {
/**
* Chartist.js plugin to display a title for 1 or 2 axises.
*
*/
/* global Chartist */
(function (window, document, Chartist) {
'use strict';
var axisDefaults = {
axisTitle: '',
axisClass: 'ct-axis-title',
offset: {
x: 0,
y: 0
},
textAnchor: 'middle',
flipText: false
};
var defaultOptions = {
xAxis: axisDefaults,
yAxis: axisDefaults
};
Chartist.plugins = Chartist.plugins || {};
Chartist.plugins.ctAxisTitle = function (options) {
options = Chartist.extend({}, defaultOptions, options);
return function ctAxisTitle(chart) {
chart.on('created', function (data) {
if (!options.axisX.axisTitle && !options.axisY.axisTitle) {
throw new Error('ctAxisTitle plugin - You must provide at least one axis title');
} else if (!data.axisX && !data.axisY) {
throw new Error('ctAxisTitle plugin can only be used on charts that have at least one axis');
}
var xPos;
var yPos;
var title;
//position axis X title
if (options.axisX.axisTitle && data.axisX) {
xPos = (data.axisX.axisLength / 2) + data.options.axisX.offset + data.options.chartPadding.left;
yPos = data.options.chartPadding.top;
if (data.options.axisX.position === 'end') {
yPos += data.axisY.axisLength;
}
title = new Chartist.Svg("text");
title.addClass(options.axisX.axisClass);
title.text(options.axisX.axisTitle);
title.attr({
x: xPos + options.axisX.offset.x,
y: yPos + options.axisX.offset.y,
"text-anchor": options.axisX.textAnchor
});
data.svg.append(title, true);
}
//position axis Y title
if (options.axisY.axisTitle && data.axisY) {
xPos = 0;
yPos = (data.axisY.axisLength / 2) + data.options.chartPadding.top;
if (data.options.axisY.position === 'end') {
xPos = data.axisX.axisLength;
}
var transform = 'rotate(' + (options.axisY.flipTitle ? -90 : 90) + ', ' + xPos + ', ' + yPos + ')';
title = new Chartist.Svg("text");
title.addClass(options.axisY.axisClass);
title.text(options.axisY.axisTitle);
title.attr({
x: xPos + options.axisY.offset.x,
y: yPos + options.axisY.offset.y,
transform: transform,
"text-anchor": options.axisY.textAnchor
});
data.svg.append(title, true);
}
});
chart.on('optionsChanged', function(data){
console.log("Saras");
});
};
};
}(window, document, Chartist));
return Chartist.plugins.ctAxisTitle;
}));
如果您在 options = Chartist.extend({}, defaultOptions, options);
行下方放置一个 console.log。您会看到选项在单击下拉菜单时发生变化......但它们实际上从未改变,除了这一次创建图表时。
现在我不知何故希望更新的选项反映在 return 函数中,但问题是你只能 return 它一次。
所以真正的问题是 如何在更新时一次又一次地调用 ctAxisTitle
函数
那么这是设计缺陷吗?是否应该更改插件的设计,如果是...如何?或者我可以以某种方式操纵代码来实现功能。
我还创建了一个 Github 存储库,以便您快速入门
在我看来,这是 angular-chartist.js
中的一个设计缺陷。如果更改了数据或选项,它们将执行以下操作:
// If chart type changed we need to recreate whole chart, otherwise we can update
if (!this.chart || newConfig.chartType !== oldConfig.chartType) {
this.renderChart();
} else {
this.chart.update(this.data, this.options);
}
因此,当他们仅在更改图表类型时重新呈现图表时,这不是您想要的。
如果您在本地有此文件,您只需修改该部分以满足您的需要,并始终通过将此行替换为 this.renderChart();
来呈现图表
有关我执行上述操作的示例,请参阅 this plunker。
好吧,这个问题可能看起来有点抽象,但让我说得更清楚一点。这是关于我试图使用名为 Chartist 的图表库解决的问题。他们有一个称为插件的系统,您可以在其中为图表添加一些附加功能。现在解释如何编写插件here and at the bottom of this page。
现在我创建了一个 plunker 来演示这个问题...我面临的问题是每当我单击下拉菜单时,axisTitle 中的值永远不会改变...
你可能会问为什么?
原因是这几行 chartist-plugin-axistitle.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], function () {
return (root.returnExportsGlobal = factory());
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// like Node.
module.exports = factory();
} else {
root['Chartist.plugins.ctAxisTitle'] = factory();
}
}(this, function () {
/**
* Chartist.js plugin to display a title for 1 or 2 axises.
*
*/
/* global Chartist */
(function (window, document, Chartist) {
'use strict';
var axisDefaults = {
axisTitle: '',
axisClass: 'ct-axis-title',
offset: {
x: 0,
y: 0
},
textAnchor: 'middle',
flipText: false
};
var defaultOptions = {
xAxis: axisDefaults,
yAxis: axisDefaults
};
Chartist.plugins = Chartist.plugins || {};
Chartist.plugins.ctAxisTitle = function (options) {
options = Chartist.extend({}, defaultOptions, options);
return function ctAxisTitle(chart) {
chart.on('created', function (data) {
if (!options.axisX.axisTitle && !options.axisY.axisTitle) {
throw new Error('ctAxisTitle plugin - You must provide at least one axis title');
} else if (!data.axisX && !data.axisY) {
throw new Error('ctAxisTitle plugin can only be used on charts that have at least one axis');
}
var xPos;
var yPos;
var title;
//position axis X title
if (options.axisX.axisTitle && data.axisX) {
xPos = (data.axisX.axisLength / 2) + data.options.axisX.offset + data.options.chartPadding.left;
yPos = data.options.chartPadding.top;
if (data.options.axisX.position === 'end') {
yPos += data.axisY.axisLength;
}
title = new Chartist.Svg("text");
title.addClass(options.axisX.axisClass);
title.text(options.axisX.axisTitle);
title.attr({
x: xPos + options.axisX.offset.x,
y: yPos + options.axisX.offset.y,
"text-anchor": options.axisX.textAnchor
});
data.svg.append(title, true);
}
//position axis Y title
if (options.axisY.axisTitle && data.axisY) {
xPos = 0;
yPos = (data.axisY.axisLength / 2) + data.options.chartPadding.top;
if (data.options.axisY.position === 'end') {
xPos = data.axisX.axisLength;
}
var transform = 'rotate(' + (options.axisY.flipTitle ? -90 : 90) + ', ' + xPos + ', ' + yPos + ')';
title = new Chartist.Svg("text");
title.addClass(options.axisY.axisClass);
title.text(options.axisY.axisTitle);
title.attr({
x: xPos + options.axisY.offset.x,
y: yPos + options.axisY.offset.y,
transform: transform,
"text-anchor": options.axisY.textAnchor
});
data.svg.append(title, true);
}
});
chart.on('optionsChanged', function(data){
console.log("Saras");
});
};
};
}(window, document, Chartist));
return Chartist.plugins.ctAxisTitle;
}));
如果您在 options = Chartist.extend({}, defaultOptions, options);
行下方放置一个 console.log。您会看到选项在单击下拉菜单时发生变化......但它们实际上从未改变,除了这一次创建图表时。
现在我不知何故希望更新的选项反映在 return 函数中,但问题是你只能 return 它一次。
所以真正的问题是 如何在更新时一次又一次地调用 ctAxisTitle
函数
那么这是设计缺陷吗?是否应该更改插件的设计,如果是...如何?或者我可以以某种方式操纵代码来实现功能。
我还创建了一个 Github 存储库,以便您快速入门
在我看来,这是 angular-chartist.js
中的一个设计缺陷。如果更改了数据或选项,它们将执行以下操作:
// If chart type changed we need to recreate whole chart, otherwise we can update
if (!this.chart || newConfig.chartType !== oldConfig.chartType) {
this.renderChart();
} else {
this.chart.update(this.data, this.options);
}
因此,当他们仅在更改图表类型时重新呈现图表时,这不是您想要的。
如果您在本地有此文件,您只需修改该部分以满足您的需要,并始终通过将此行替换为 this.renderChart();
有关我执行上述操作的示例,请参阅 this plunker。