小编hen*_*nit的帖子

ReactJS表单组件的最佳实践

我正在寻找最佳实践,让ReactJS组件负责用户编辑给定实体的表单.这里非常简化的例子.在许多情况下,实际表单会有更多字段和更多GUI功能.

React.createClass({
    getInitialState: function() {
        return {
            entity: {
                property1: null,
                property2: null
            }
        };
    },

    handleChange: function(e) {
        var entity = this.state.entity;

        switch(e.target.name) {
            case 'property1':
                entity.property1 = e.target.value;
                break;
            case 'property2':
                entity.property2 = e.target.value;
                break;
        }

        this.setState({
            entity: entity
        });
    },

    render: function() {
        return (
            <div className="entity-form">
                <form onChange={this.handleChange}>
                    <input type="text" name="property1" value={this.state.entity.property1} />
                    <br />

                    <textarea name="property2" value={this.state.entity.property2}></textarea>
                    <br />
                </form>
            </div>
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

表单的字段直接编辑实体对象,然后可以将其保存到RESTful api.我希望在用户更改字段时更新组件,因此GUI可以在键入期间根据输入做出反应(如验证,信息等).

从理论上讲,我可以让整个状态对象代表正在编辑的实体,因此实体的每个属性都是第一级状态变量.但是,我希望能够为GUI函数添加额外的状态变量以及与组件将要执行的操作相关的其他事情,因此我更希望实体对象是一个状态变量,如上面的"实体"状态变量.该对象当然可以是一些更复杂的对象,如Backbone模型或类似对象,但在这个简化的示例中,我只使用一个简单的对象,具有所需的属性.

因此,为了寻找为此目的制作React组件的最佳实践方法,我有一些问题:

  1. 道具或州.

在这种情况下,我选择将带有表单内容的实体对象放在状态变量而不是prop中.这是为了能够在表单输入期间更新对象,而无需调用父级并更新道具.就我的React经验而言,这将是像这样的表单组件的最佳实践.

  1. 受控或不受控制的输入.

在上面的简化示例中,我使用受控输入.这导致更新状态并在每次更改时重新呈现组件(例如,输入文本字段的每个字符).这是最好的做法吗?好处是组件可以完全控制发生的事情,而不是使用defaultValue参数,并且在某些事件上(如用户按下保存按钮),组件提取值,更新实体并将其保存到服务器.如果在这种情况下应该使用受控或不受控制的输入,是否有任何理由(或意见)?

  1. onChange表单或每个输入

该示例在表单标记上有一个onChange,每次更改表单中的任何字段时,都会调用handleChange方法.但是,由于输入是受控制的(具有值参数),React会抱怨输入字段没有onChange属性.这是否意味着在表单标记上有一个共同的onChange是不好的做法,我应该删除它并在每个字段上放置onChange而不是?

  1. 更新个别属性 …

javascript forms reactjs

30
推荐指数
1
解决办法
1万
查看次数

基于Shadow DOM root的字体大小css值

问题简述:

我正在寻找一种方法来设置基于字体大小的值(类似于将一些属性设置为em值)在阴影dom内相对于阴影主机的元素内,而不管阴影dom中父元素的字体大小.类似于rem-values的工作原理,但是阴影是root而不是html root.

这样做的原因是能够在一个地方缩放像小部件(插入阴影dom)的内容.如果可以通过这种方式缩放基于字体大小的属性,则可以在每个上下文中缩放整个窗口小部件,而无需设置大量css值以使其适合每个位置.

问题的详细描述:

我正在寻找一种基于DOM中的给定元素来调整文本大小(font-size)的方法,以便能够基于此包装元素缩放该元素内的不同内容部分(适用于小部件等).这不仅仅适用于实际文本,通常很好地基于font-size来设置很多css值,因此元素的可视化布局与文本的大小(如填充,边框半径和阴影)一致.如果一切都基于em值,这可能会有点混乱.如果元素中有多个级别的字体大小继承,并且我想在不改变第二级的情况下放大第一级,我需要放大dom中第一级的em,同时减少任何二级元素(基于第一级计算)使子元素的文本保持相同的大小.在许多情况下,这不是最佳的.

一个很好的解决方案是基于Root EM(rem),因此更改dom的一个级别不会影响子元素.但是,如果我想放大/缩小这个包装元素内的所有文本的大小(在一个地方)而不影响同一页面上的其他元素,我需要放大/缩小所有字体大小的rem值.包装元素内的元素.

我最近开始研究使用Shadow DOM和模板的Web组件.在模板标签中,css是封装的,因为该框/小部件/组件的设计可以独立设计,而不必考虑设计的其余部分,不需要的继承值等.最后是制作独立组件以构建网页的好方法.但是,如果我可以为模板本身设置一种模板根字体大小,那就太好了.因此,如果我将模板中的某些元素设置为font-size 2rem(或任何其他类似单位),那么该元素的字体大小将是模板的根字体大小的2倍,而不管主机中的字体大小如何使用该模板的元素,无论页面根目录的字体大小(html元素)如何.

当我在模板中使用rem-values进行测试时,它仍然基于页面根(html标签)font-size.我也测试了vw值,但这也是基于整个视口,而不仅仅是封装区域(阴影根).

我看过很多关于Shadow DOM的文章,但我还没有找到任何关于这个问题的解决方案.有什么建议?

会发生什么(简化示例):

<html style="font-size: 16px">
    <body style="font-size: 12px">
        I am 12px large

        <!-- em, based on the body in this case -->
        <div style="font-size: 1.5em">
            I am 18px large

            <div style="font-size: 1.5em">
                I am 27px large
            </div>
        </div>

        <!-- rem, based on the styles of the html element -->
        <div style="font-size: 1.5rem">
            I am 24px large

            <div style="font-size: 1.5rem">
                I am 24px large
            </div>
        </div>
    </body>
</html> …
Run Code Online (Sandbox Code Playgroud)

html css dom css3 web-component

20
推荐指数
1
解决办法
2625
查看次数

Symfony不验证对象约束

我有一个Silex项目,我使用FormServiceProvider和ValidatorServiceProvider.我使用form.factory构建器创建了一个表单,添加了字段,并使用对象作为数据集:

$form = $app['form.factory']->createBuilder('form', $object)
Run Code Online (Sandbox Code Playgroud)

然后我尝试在"正常方式"上验证表格:

if ($app['request']->getMethod() == 'POST') {
    $form->bind($app['request']);
    if ($form->isValid()) {
        (...)
    }
}
Run Code Online (Sandbox Code Playgroud)

在对象中,我添加了一个loadValidatorMetadata静态方法:

static public function loadValidatorMetadata(ClassMetadata $metadata) {
    $metadata->addPropertyConstraint('name', new Assert\MinLength(5, array('message' => 'Name too short')));
}
Run Code Online (Sandbox Code Playgroud)

当我使用较短的名称字段提交表单时,isValid仍然返回true.如果我在对象上运行一个validate方法,如下所示:

$errors = $app['validator']->validate($object)
Run Code Online (Sandbox Code Playgroud)

它根据约束返回错误,但表单isValid未找到此错误.当我查看symfony Form类时,我发现当disable config为true时,isValid会跳过检查子字段.这是我的表格的情况,但我不知道为什么.我刚刚以正常方式注册了Silex服务提供商,没有任何特殊配置.知道如何根据对象约束使表单失败验证吗?

forms validation constraints symfony silex

5
推荐指数
1
解决办法
779
查看次数

React.PureComponent没有实现shouldComponentUpdate

我可能会缺少一些东西,但是我有一个像这样的组件

export default MyComponent extends React.PureComponent {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果MyComponent是另一个组件渲染方法的一部分,则即使父项/状态未更改,MyComponent也会在每次父项渲染时重新渲染。因此,似乎从更改React.ComponentReact.PureComponent并没有使组件“纯净”。

我尝试添加

console.info(this.shouldComponentUpdate)
Run Code Online (Sandbox Code Playgroud)

里面的组件方法之一,它说它是未定义的。不React.PureComponent应该添加一个浅表比较shouldComponentUpdate方法吗?

React 15.5.415.6.0现在已经发生了这种情况

ecmascript-6 reactjs

5
推荐指数
1
解决办法
2406
查看次数

mongodb 转储和管道到其他数据库名称

MongoDB 版本 3.2.12。我有两个本地数据库,“base1”和“base2”

我想将所有数据(所有集合)从 base1 复制到 base2,替换那里的所有内容(例如将生产转储到开发环境时)。

任何管道命令(或其他简单的方法)来做到这一点?

我试过

mongodump --archive --db base1 | mongorestore --db base2 --archive
Run Code Online (Sandbox Code Playgroud)

列出了很多“将 base1.collectionname 写入标准输出存档”,但没有写入 base2。

我也试过

mongodump --db base1 --gzip --archive=/path/to/file.gz
mongorestore --db base2 --gzip --archive=/path/to/file.gz
Run Code Online (Sandbox Code Playgroud)

转储工作,恢复只是说“为存档创建意图”,“完成”

mongodb mongorestore mongodump

4
推荐指数
1
解决办法
2206
查看次数

使用Silex SessionServiceProvider时,PHPUnit失败

我正在尝试为我的Silex应用程序创建一个单元测试.单元测试类看起来像这样:

class PageTest extends WebTestCase {

    public function createApplication() {
        $app = require __DIR__ . '/../../app/app.php';
        $app['debug'] = true;

        $app['session.storage'] = $app->share(function() {
            return new MockArraySessionStorage();
        });

        $app['session.test'] = true;

        unset($app['exception_handler']);
        return $app;
    }

    public function testIndex() {
        $client = $this->createClient();
        $client->request('GET', '/');
        $this->assertTrue($client->getResponse()->isOk());
    }

}
Run Code Online (Sandbox Code Playgroud)

和它试图请求的silex路径看起来像这样:

$app->get('/', function() use($app) {
    $user     = $app['session']->get('loginUser');

    return $app['twig']->render('views/index.twig', array(
        'user'           => $user,
    ));
});
Run Code Online (Sandbox Code Playgroud)

这会导致RuntimeException:由于已经发送了标头,因此无法启动会话.\ Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage.php:142中有一个回溯,其中包含来自$ app ['session'] - > get的路线中的行.

看起来在NativeSessionStorage中会话开始尝试之前发生的输出实际上是PHPUnit输出信息,因为这是我在错误消息之前得到的唯一输出:

PHPUnit 3.7.8 by Sebastian Bergmann.

Configuration …
Run Code Online (Sandbox Code Playgroud)

session phpunit header silex

3
推荐指数
1
解决办法
1373
查看次数