如何改进标准控制

好的,我已经按照您的要求,将 HTML 内容中的文本翻译成了通俗易懂的中文,同时严格保留了所有 HTML 标签、属性和结构,并原样保留了形如 <pre><code> frappe.ui.form.ControlData = frappe.ui.form.ControlData.$extend({ make_input: function(){ var options = this.df.options; if (!options || options!=="Translatable"){ this._super(); return; } var me = this; $('\ \ \ \\ \ ').prependTo(this.input_area); this.$input_area = $(this.input_area); this.$input = this.$input_area.find('input'); this.$btn = this.$input_area.find('.dialog-btn'); this.set_input_attributes(); this.$input.on("focus", function(){ me.$btn.toggle(true); }); this.$input.on("blur", function(){ setTimeout(function(){ me.$btn.toggle(false) }, 500); }); this.input = $this.input.get(0); this.has_input = true; var me = this; this.setup_button(); }, setup_button: function(){ var me = this; if (this.only_input){ this.$btn.remove(); return; } this.$btn.on("click", function(){ var value = me.get_value(); var options = me.df.options; if (value && options && options==="Translatable"){ this.open_dialog(); } }); }, open_dialog: function(){ if (this.frm && !this.frm.is_dirty()) { new frappe.ui.form.TranslationSelector({ doc: doc, df: this.doc, text: this.value }); } } }); 的代码块占位符。


<article :class="{ 'opacity-50': $store.navigation.loading, 'xl:!max-w-[100ch]': $store.sidebar?.isCollapsed }" class="min-w-0 w-full transition-opacity duration-300 xl:max-w-[85ch]">
<!-- 页面头部 -->

<!-- 页面内容 -->
<!-- prose prose-v3 镜像了 SPA 编辑器中的 EditorContent 默认样式 -->
<div class="prose prose-v3 !max-w-none" id="wiki-content">
<p>Frappe 有一些优雅且实用的控件,但有时我们需要对它们进行修改以添加一些小的改进。这篇小文章将介绍如何向标准控件中添加新的资源。</p>
<p>首先,让我解释一下我们的目标:</p>
<blockquote>
<p>在 <code>numerous records 和 lot of doctypes 中添加 many 的替代翻译

看看目标中高亮的部分,我们需要在许多记录和许多文档类型中添加许多翻译,因此,我们有很多工作要做,对吧?

这个问题的答案是:-当然不是!因为我们知道,如果一个元素存在于许多记录和许多文档类型中,那么这个元素就是 Control 或 Widget

所以,我们需要做的是,基于 Control 来改进你的目标,以减少我们的工作量。

但是,我们将在哪里找到这个神奇的元素,即控件呢?-目前,我们可以在 JavaScript 源码中查看它 - 现在让我们看看 Github

如果现在看不懂代码,请不要担心,我们的目标是简化我们的工作。

让我们继续思考!

我们知道需要在何处进行更改,但我们如何区分哪些控件受我们功能的影响,哪些不受影响呢?

我们需要记住,Control 是 DocFields 的实例,并且 DocFields 有一个字段在这种情况下对我们非常重要,这个能帮助我们区分哪些受功能影响、哪些不受影响的字段是 DocField 中的 options 字段。

-等等!我们明白了 options 字段可以帮助我们,但是,它将如何帮助我们呢?

问得好,我们将定义一个词,放在我们需要包含该功能的 DocFields 的 options 中,这个词将是 Translatable。

如果你忘记了如何自定义字段的选项,可以看看这篇文章,它能帮你复习一下相关知识。

好了,在我们选定的 DocFields 的 options 中定义了关键词后,现在是时候编写代码了:

-终于,我们以为我们永远不会停止讨论呢!

 frappe.ui.form.ControlData = frappe.ui.form.ControlData.$extend({
 make_input: function(){
 var options = this.df.options;
 if (!options || options!=="Translatable"){
 this._super();
 return;
 }
 var me = this;
 $('\
 \
 \
 \\
 \
 ').prependTo(this.input_area);
 this.$input_area = $(this.input_area);
 this.$input = this.$input_area.find('input');
 this.$btn = this.$input_area.find('.dialog-btn');
 this.set_input_attributes();
 this.$input.on("focus", function(){
 me.$btn.toggle(true);
 });
 this.$input.on("blur", function(){
 setTimeout(function(){ me.$btn.toggle(false) }, 500);
 });
 this.input = $this.input.get(0);
 this.has_input = true;
 var me = this;
 this.setup_button();
 },
 setup_button: function(){
 var me = this;
 if (this.only_input){
 this.$btn.remove();
 return;
 }
 this.$btn.on("click", function(){
 var value = me.get_value();
 var options = me.df.options;
 if (value && options && options==="Translatable"){
 this.open_dialog();
 }
 });
 },
 open_dialog: function(){
 if (this.frm && !this.frm.is_dirty()) {
 new frappe.ui.form.TranslationSelector({
 doc: doc,
 df: this.doc,
 text: this.value
 });
 }
 }
 });

-我的天,又是一堆字母汤!

事实上,对于新手来说,它确实是一堆字母汤,但我们不是初学者。

让我解释一下这段代码的作用;

  • 第 1 行,代码通过其自身的扩展 Class 覆盖了 ControlData。
  • 方法 make_input 检查 docfield 是否为 Translatable,以创建新的 Control,如果不是,则使用 _super() 调用原始的 make_input。
  • 方法 setup_button 检查 docfield 是否为 Translatable,以启用它显示一个 dialog。
  • 方法 open_dialog 调用我们将在下面代码中创建的 TranslationSelector 的一个新实例。