zsmj
2 years ago
7 changed files with 236 additions and 69 deletions
After Width: | Height: | Size: 55 KiB |
@ -1 +1,47 @@
|
||||
# FineUI中如何格式化输出日期 |
||||
# FineUI中如何格式化输出日期 |
||||
|
||||
`BI.print(date,formatStr)` |
||||
|
||||
如果你不知道用什么,那么直接`%Y-%X-%d %H:%M:%S` |
||||
|
||||
约定当前日期为2022年十月八日 |
||||
|
||||
## 输出基本年月日格式 |
||||
|
||||
```javascript |
||||
BI.print(BI.getDate(), "%Y-%X-%d") // '2022-10-08' |
||||
BI.print(BI.getDate(), "%Y-%x-%e") // '2022-10-08' |
||||
BI.print(BI.getDate(), "%X/%d/%Y") // '10/08/2022' |
||||
``` |
||||
|
||||
## 输出时分秒格式 |
||||
|
||||
```javascript |
||||
BI.print(BI.getDate(), "%H:%M:%S") // '16:14:26' |
||||
BI.print(BI.getDate(), "%I:%M:%S") // '04:14:26' |
||||
BI.print(BI.getDate(), "%k:%M:%S") // '16:14:26' |
||||
BI.print(BI.getDate(), "%l:%M:%S") // '4:14:26' |
||||
``` |
||||
|
||||
## AM与PM区分 |
||||
```javascript |
||||
BI.print(BI.getDate(), "%l:%M:%S %p") // '4:26:12 PM' |
||||
BI.print(BI.getDate(), "%l:%M:%S %P") // '4:26:12 pm' |
||||
``` |
||||
|
||||
## 星期 |
||||
```javascript |
||||
BI.print(BI.getDate(), "%Y-%X-%d %u") // '2022-10-08 7' the day of the week (range 1 to 7, 1 = MON) |
||||
BI.print(BI.getDate(), "%Y-%X-%d %w") // '2022-10-08 6' the day of the week (range 0 to 6, 0 = SUN) |
||||
``` |
||||
|
||||
## 每年的第几周 |
||||
```javascript |
||||
BI.print(BI.getDate(), "%Y-%W") // '2022-40' |
||||
``` |
||||
|
||||
## 季度 |
||||
```javascript |
||||
BI.print(BI.getDate(), "%Y-%Q") // '2022-4' |
||||
BI.print(BI.getDate(), "%Y-%q") // '2022-04' |
||||
``` |
||||
|
@ -1 +1,11 @@
|
||||
# 如何监听元素大小变化 |
||||
# 如何监听元素大小变化 |
||||
|
||||
广义上讲,FineUI中有两种监听大小变化的方法 |
||||
|
||||
`BI.Resizers.add`和`BI.ResizeDetector.addResizeListener` |
||||
|
||||
严格意义上讲`BI.Resizers.add`并不算是监听元素大小变化,其底层实现是监听window的resize事件,只有窗口大小改变时候会触发,多用于combo,layer等自动调整位置的组件. |
||||
|
||||
`BI.ResizeDetector.addResizeListener`则是真实的监听组件元素大小改变,常用于计算动态宽高等场景 |
||||
|
||||
注意事项:有添加监听必有取消监听,要注意再组建销毁时移除掉事件监听,有两种形式,一种是在添加监听的方法会返回一个移除当前监听的函数,调用即可.另一种是调用`BI.Resizers.remove`和`BI.ResizeDetector.removeResizeListener`方法 |
||||
|
@ -1,63 +0,0 @@
|
||||
let selectedValues = ["1", "2"]; |
||||
|
||||
var Model = BI.inherit(Fix.Model, { |
||||
state: function () { |
||||
return { |
||||
selectedValues: ["1", "2"], |
||||
} |
||||
}, |
||||
computed: { |
||||
selectedNodes: function () { |
||||
return this.model.selectedValues; |
||||
} |
||||
}, |
||||
actions: { |
||||
setSelectedValue: function (v) { |
||||
this.model.selectedValues = v; |
||||
} |
||||
} |
||||
}) |
||||
BI.model("demo_chooser_combo", Model); |
||||
|
||||
var model = BI.Models.getModel("demo_chooser_combo"); |
||||
|
||||
BI.createWidget({ |
||||
type: "bi.value_chooser_no_bar_combo", |
||||
ref: (_ref) => { |
||||
this.combo = _ref; |
||||
}, |
||||
value: model.model.selectedValues, |
||||
items: [ |
||||
{ |
||||
text: "11", |
||||
value: "1", |
||||
disabled: () => { |
||||
var isSelected = !!model.model.selectedNodes.find(value => value === "1"); |
||||
return !isSelected && model.model.selectedNodes.length >= 2; |
||||
} |
||||
}, { |
||||
text: "22", |
||||
value: "2", |
||||
disabled: () => { |
||||
var isSelected = !!model.model.selectedNodes.find(value => value === "2"); |
||||
return !isSelected && model.model.selectedNodes.length >= 2; |
||||
} |
||||
}, { |
||||
text: "33", |
||||
value: "3", |
||||
disabled: () => { |
||||
var isSelected = !!model.model.selectedNodes.find(value => value === "3"); |
||||
return !isSelected && model.model.selectedNodes.length >= 2; |
||||
} |
||||
} |
||||
], |
||||
listeners: [ |
||||
{ |
||||
eventName: BI.ValueChooserNoBarCombo.EVENT_CLICK_ITEM, |
||||
action: () => { |
||||
const selectedNodesID = this.combo.getValue(); |
||||
model.setSelectedValue(selectedNodesID); |
||||
}, |
||||
} |
||||
] |
||||
}); |
@ -0,0 +1,86 @@
|
||||
# 在响应式中谨慎使用解构 |
||||
|
||||
在刚接触编程的时候,我们就学过条件语句中断的特性,在Fix编程中,我们的computed计算属性有很多使用逻辑判断语句的. |
||||
|
||||
**如果某个响应式属性与依赖某个state,那么在书写响应式属性取值函数时需要确保对响应式数据的获取在取值函数内发生.** |
||||
|
||||
即`value = > get observe data and return` |
||||
|
||||
结合一个实际场景举例: |
||||
demo代码如下,label的text属性采用响应式形式,min和max提前做了解构,那么当label点击触发修改状态之后,label的文本会随之改变吗?答案显而易见是不会的,因为违背了上面的原则,在text属性的计算函数外获取的state属性 |
||||
|
||||
|
||||
```javascript |
||||
const Model = BI.inherit(Fix.Model, { |
||||
state: function () { |
||||
return { |
||||
max: 38, |
||||
min: 22, |
||||
}; |
||||
}, |
||||
|
||||
actions: { |
||||
upup: function () { |
||||
this.model.max++; |
||||
this.model.min++; |
||||
}, |
||||
}, |
||||
}); |
||||
BI.model("demo", Model); |
||||
|
||||
const DemoWidget = BI.inherit(BI.Widget, { |
||||
_store: function () { |
||||
return BI.Models.getModel("demo"); |
||||
}, |
||||
|
||||
render: function () { |
||||
|
||||
const { min, max } = this.model; |
||||
|
||||
return { |
||||
type: "bi.label", |
||||
height: 32, |
||||
text: () => `最高气温: ${max} 最低气温: ${min}`, |
||||
handler: () => { |
||||
this.store.upup(); |
||||
}, |
||||
}; |
||||
}, |
||||
}); |
||||
BI.shortcut("demo_widget", DemoWidget); |
||||
|
||||
const Demo = BI.createWidget({ |
||||
type: "demo_widget", |
||||
}); |
||||
``` |
||||
|
||||
调整方式也很容易,将state获取写入函数体内 |
||||
|
||||
```javascript |
||||
render: function () { |
||||
return { |
||||
type: "bi.label", |
||||
height: 32, |
||||
text: () => `最高气温: ${this.model.max} 最低气温: ${this.model.min}`, |
||||
handler: () => { |
||||
this.store.upup(); |
||||
}, |
||||
}; |
||||
}, |
||||
``` |
||||
或者在函数体内解构,同样是在函数内部获取state属性 |
||||
```javascript |
||||
render: function () { |
||||
return { |
||||
type: "bi.label", |
||||
height: 32, |
||||
text: () => { |
||||
const { min, max } = this.model; |
||||
return `最高气温: ${max} 最低气温: ${min}`; |
||||
}, |
||||
handler: () => { |
||||
this.store.upup(); |
||||
}, |
||||
}; |
||||
}, |
||||
``` |
@ -1,7 +1,92 @@
|
||||
# watch使用的常见误区 |
||||
|
||||
示例 |
||||
|
||||
https://code.fineres.com/projects/DEC/repos/decision-webui/pull-requests/7973/diff#src/modules/management/authority/carrierdimenision/entities/system/system.authority.js |
||||
## watch职责不单一,掺杂额外处理逻辑 |
||||
|
||||
![示例](../images/1.png) |
||||
最常见的场景为在watch中掺杂调用loading和loaded方法.这样做的弊端在于loading状态的控制没有形成明显闭环,有可能出现loading触发了,但是没有后续的loaded,导致用于在加载中 |
||||
|
||||
```javascript |
||||
watch: { |
||||
items: function (items) { |
||||
this.loading(); |
||||
// do someting |
||||
}, |
||||
}, |
||||
``` |
||||
比较合理的做法是在触发异步获取数据的action中进行loading状态的切换,即异步请求发起前状态切换到loading,请求结束后切换到loaded |
||||
```javascript |
||||
// model.js |
||||
actions: { |
||||
getItems: function (items) { |
||||
this.model.loading = true; |
||||
requestItems().then(() => { |
||||
// do something |
||||
this.model.loaded = false; |
||||
}); |
||||
}, |
||||
}, |
||||
|
||||
// widget.js |
||||
watch: { |
||||
loading: function (b) { |
||||
b : this.loading() : this.loaded(); |
||||
}, |
||||
}, |
||||
``` |
||||
|
||||
## 在组件的watch中回过头来调用store中的action |
||||
|
||||
类似于经济上的出口转内销,在watch中调用action修改状态,进而触发另外的watch. |
||||
这样是不优雅的,实际业务中确实存在watch某个状态改变触发action的场景,例如通过watch上层的keyword状态,触发搜索action. |
||||
很多同学忽视了其实store中也可以进行watch的,合理的实现是将状态改变全都放在store里,在store中进行watch |
||||
|
||||
不佳的实现 |
||||
```javascript |
||||
// model.js |
||||
context: ["keyword"], |
||||
|
||||
state: function () { |
||||
return { |
||||
b: 22, |
||||
}; |
||||
}, |
||||
|
||||
actions: { |
||||
changeB: function () { |
||||
this.model.b++; |
||||
}, |
||||
}, |
||||
|
||||
// widget.js |
||||
watch: { |
||||
keyword: function () { |
||||
this.store.changeB(); |
||||
}, |
||||
}, |
||||
``` |
||||
更为合理的实现 |
||||
```javascript |
||||
// model.js |
||||
context: ["keyword"], |
||||
|
||||
state: function () { |
||||
return { |
||||
b: 22, |
||||
}; |
||||
}, |
||||
|
||||
watch: { |
||||
keyword: function () { |
||||
this.store.changeB(); |
||||
}, |
||||
}, |
||||
|
||||
actions: { |
||||
changeB: function () { |
||||
this.model.b++; |
||||
}, |
||||
}, |
||||
``` |
||||
|
||||
业务代码示例 |
||||
![示例](../images/45.png) |
||||
|
Loading…
Reference in new issue