首页 \ 问答 \ 如果没有fileupload文件选择,则禁用提交按钮(Disable Submit Button if No fileupload File Chosen)

如果没有fileupload文件选择,则禁用提交按钮(Disable Submit Button if No fileupload File Chosen)

我为客户制作了一个表单,通过五种不同的文件上载来上传一个或多个文档。 我想禁用整个表单的提交按钮,除非为其中一个文件上载选择了至少一个文件(无关紧要)。

提前致谢!


I made a form for clients to upload one or more documents through five different fileuploads. I'd like to disable the submit button for the entire form unless at least one file is chosen for one of the fileuploads (doesn't matter which one).

Thanks in advance!


原文:https://stackoverflow.com/questions/16846637
更新时间:2022-10-12 10:10

最满意答案

依赖注入是您正在寻找的解决方案。 一般问题与创建依赖项的位置有关。 通常,在编写面向对象的程序时,自然的本能是使用您需要依赖项的位置处的new关键字直接创建依赖项。 有时您可能会在构造函数中创建长期存在的依赖项。

为了使您的类更可单元测试,您需要“反转”该规范,并在外部创建您的依赖项(或创建一个工厂/提供程序/上下文,然后可以注入并用于创建其他依赖项的实例),并且“注入” “那些依赖于你的班级。 两种最常见的注入机制既可以作为构造函数的参数,也可以作为带有setter的属性。 通过以这种方式外部化依赖关系管理,您可以轻松地创建这些依赖关系的模拟版本并将其传递,从而允许您完全隔离应用程序的其余部分来测试代码单元。

为了支持依赖注入并使其更容易管理Inversion of Control(IoC)容器已经出现。 IoC容器是一个框架,允许您独立于参与这些图的类配置依赖关系图。 一旦配置了依赖关系图(通常以感兴趣的单个关键类为根),您就可以在运行时轻松创建对象的实例,而无需担心手动创建所有必需的依赖关系。 这有助于创建非常松散耦合,灵活的代码,易于重新配置。 一个非常好的IoC容器的例子是Castle Windsor ,它提供了一个非常丰富的框架,用于通过依赖注入来连接类。

一个非常简单的依赖注入示例如下所示:

interface ITaskService
{
    void SomeOperation();
}

interface IEntityService
{
    Entity GetEntity(object key);
    Entity Save(Entity entity);
}

class TaskService: ITaskService
{
    public TaskService(EntityServiceFactory factory)
    {
        m_factory = factory;
    }

    private EntityServiceFactory m_factory; // Dependency

    public void SomeOperation() // Method must be concurrent, so create new IEntityService each call
    {
        IEntityService entitySvc = m_factory.GetEntityService();
        Entity entity = entitySvc.GetEntity(...);
        // Do some work with entity
        entitySvc.Save(entity);
    }
}

class EntityServiceFactory
{
    public EntityServiceFactory(RepositoryProvider provider)
    {
        m_provider = provider;
    }

    private RepositoryProvider m_provider; // Dependency

    public virtual IEntityService GetEntityService()
    {
        var repository = m_provider.GetRepository<Entity>();
        return new EntityService(repository);
    }
}

class EntityService: IEntityService
{
    public EntityService(IEntityRepository repository)
    {
        m_repository = repository;
    }

    private IEntityRepository m_repository; // Dependency

    public Entity GetEntity(object key)
    {
        if (key == null) throw new ArgumentNullException("key");

        // TODO: Check for cached entity here?

        Entity entity = m_repository.GetByKey(key);
        return entity;
    }

    public Entity Save(Entity entity)
    {
        if (entity == null) throw new ArgumentNullException(entity);

        if (entity.Key == null)
        {
            entity = m_repository.Insert(entity);
        }
        else
        {
            m_repository.Update(entity);
        }

        return entity;
    }
}

class RepositoryProvider
{
    public virtual object GetRepository<T>()
    {
        if (typeof(T) == typeof(Entity))
            return new EntityRepository();
        else if (...)
            // ... etc.
    }
}

interface IEntityRepository
{
    Entity GetByKey(object key);
    Entity Insert(Entity entity);
    void Update(Entity entity);
}

class EntityRepository: IEntityRepository
{
    public Entity GetByKey(object key)
    {
        // TODO: Load up an entity from a database here
    }

    public Entity Insert(Entity entity)
    {
        // TODO: Insert entity into database here
    }

    public void Update(Entity entity)
    {
        // TODO: Update existing entity in database here
    }
}

Dependency Injection is the solution you are looking for. The general problem has to do with where your dependencies are created. Normally, when writing an object-oriented program, the natural instinct is to create your dependencies directly using the new keyword at the location you need your dependencies. Sometimes you may create long-lived dependencies in a constructor.

To make your classes more unit testable, you need to "invert" that norm, and create your dependencies externally (or create a factory/provider/context that can in turn be injected and used to create instances of other dependencies), and "inject" those dependencies into your class. The two most common mechanisms of injection are either as parameters to a constructor, or with properties with setters. By externalizing dependency management in this way, you are easily able to create mocked versions of those dependencies and pass those in, allowing you to test your units of code in full isolation from the rest of your application.

To support dependency injection and make it easier to manage Inversion of Control (IoC) containers have appeared. An IoC container is a framework that allows you to configure dependency graphs independently of the classes that participate in in those graphs. Once a dependency graph is configured (usually rooted at the single key class of interest), you can easily create instances of your objects at runtime without having to worry about manually creating all of the required dependencies as well. This helps in creating very loosely coupled, flexible code that is easy to reconfigure. An example of a very good IoC container is Castle Windsor, which provides a very rich framework for wiring up classes via dependency injection.

A very simple example of Dependency Injection would be something like the following:

interface ITaskService
{
    void SomeOperation();
}

interface IEntityService
{
    Entity GetEntity(object key);
    Entity Save(Entity entity);
}

class TaskService: ITaskService
{
    public TaskService(EntityServiceFactory factory)
    {
        m_factory = factory;
    }

    private EntityServiceFactory m_factory; // Dependency

    public void SomeOperation() // Method must be concurrent, so create new IEntityService each call
    {
        IEntityService entitySvc = m_factory.GetEntityService();
        Entity entity = entitySvc.GetEntity(...);
        // Do some work with entity
        entitySvc.Save(entity);
    }
}

class EntityServiceFactory
{
    public EntityServiceFactory(RepositoryProvider provider)
    {
        m_provider = provider;
    }

    private RepositoryProvider m_provider; // Dependency

    public virtual IEntityService GetEntityService()
    {
        var repository = m_provider.GetRepository<Entity>();
        return new EntityService(repository);
    }
}

class EntityService: IEntityService
{
    public EntityService(IEntityRepository repository)
    {
        m_repository = repository;
    }

    private IEntityRepository m_repository; // Dependency

    public Entity GetEntity(object key)
    {
        if (key == null) throw new ArgumentNullException("key");

        // TODO: Check for cached entity here?

        Entity entity = m_repository.GetByKey(key);
        return entity;
    }

    public Entity Save(Entity entity)
    {
        if (entity == null) throw new ArgumentNullException(entity);

        if (entity.Key == null)
        {
            entity = m_repository.Insert(entity);
        }
        else
        {
            m_repository.Update(entity);
        }

        return entity;
    }
}

class RepositoryProvider
{
    public virtual object GetRepository<T>()
    {
        if (typeof(T) == typeof(Entity))
            return new EntityRepository();
        else if (...)
            // ... etc.
    }
}

interface IEntityRepository
{
    Entity GetByKey(object key);
    Entity Insert(Entity entity);
    void Update(Entity entity);
}

class EntityRepository: IEntityRepository
{
    public Entity GetByKey(object key)
    {
        // TODO: Load up an entity from a database here
    }

    public Entity Insert(Entity entity)
    {
        // TODO: Insert entity into database here
    }

    public void Update(Entity entity)
    {
        // TODO: Update existing entity in database here
    }
}

相关问答

更多
  • 首先要做的事情......正如你注意到的,当你的单元测试(复杂的VM初始化)时,你当前的设置可能会有问题。 但是,简单地遵循DI原则 , 取决于抽象,而不是结核 ,使问题立即消失。 如果你的视图模型会实现接口,并且依赖关系可以通过接口实现,那么任何复杂的初始化都将变得无关紧要,因为在测试中你只需使用mock。 接下来,带注释属性的问题是,您在视图模型和Unity之间创建了高度耦合 (这就是为什么它很可能是错误的原因)。 理想情况下,注册应该在单个顶级点(在您的情况下是引导程序)处理,因此容器不会以任何方式绑 ...
  • Mike Clifton在2004年描述了24种测试模式。它是设计单元测试时的有用启发式的。 http://www.codeproject.com/Articles/5772/Advanced-Unit-Test-Part-V-Unit-Test-Patterns 通过/失败模式 这些模式是您的第一道防线(或攻击,取决于您的观点),以保证良好的代码。 但是要警告,他们在告诉你代码方面是欺骗性的。 简单测试模式 代码路径模式 参数范围模式 数据交易模式 数据交易模式是开始涉及数据持久性和通信的问题。 有关此主 ...
  • 依赖注入是您正在寻找的解决方案。 一般问题与创建依赖项的位置有关。 通常,在编写面向对象的程序时,自然的本能是使用您需要依赖项的位置处的new关键字直接创建依赖项。 有时您可能会在构造函数中创建长期存在的依赖项。 为了使您的类更可单元测试,您需要“反转”该规范,并在外部创建您的依赖项(或创建一个工厂/提供程序/上下文,然后可以注入并用于创建其他依赖项的实例),并且“注入” “那些依赖于你的班级。 两种最常见的注入机制既可以作为构造函数的参数,也可以作为带有setter的属性。 通过以这种方式外部化依赖关系管 ...
  • 这里的问题是你没有足够的抽象。 抽象/接口的要点是定义一个以技术无关的方式暴露行为的合约。 换句话说,您为EFDbContext创建了一个接口是一个很好的第一步,但该接口仍然与具体实现 - DbSet(DbSet)绑定。 对此的快速解决方法是将此属性作为IDbSet而不是DbSet公开。 理想情况下,你公开的东西更像IQueryable这样抽象(尽管这不会给你Add()方法等)。 越抽象,越容易模拟。 然后,您将完成您依赖的“合同”的其余部分 - 即SaveChanges()方法。 您的更新代码如下所示: ...
  • 如果我正确理解你的问题,那么它应该是为你的页面创建特殊的虚拟后台bean,然后创建一个将这些bean映射到.jspx文件的测试JSF配置文件。 虚拟bean当然不会触及任何业务逻辑或后端服务 - 它们只是简单的数据集,在测试中很容易验证。 创建一个ant脚本来代替你的虚拟后台bean和测试配置文件。 运行你的测试。 如果你不想要像HTTPUnit那样沉重的东西,并且如果你在你的应用程序中使用Spring,那么看看这篇博客文章,提供了一种在没有Web服务器的情况下模拟完整Web上下文的绝佳方法。 您的测试可能 ...
  • 国际海事组织,提出一种方法来测试你正在编写的代码将不会比它的价值更麻烦。 通过良好的测试,可以更轻松地获得新功能的工作,修复错误并维护应用程序。 根据您所描述的内容,我认为您需要决定哪种测试更适合您的情况:单元测试或集成测试。 如果您想编写真正的单元测试,那么您将不得不抽象出命令行工具,以便您可以针对实体返回相同的预期响应的实体编写测试。 如果您创建一个接口来将调用包装到命令行工具中,那么您可以轻松地嘲笑响应。 如果您使用这种方法,那么务必记住您正在测试的是您的服务按照预期对命令行工具的输出做出响应。 你必 ...
  • 在按钮单击事件中放入一堆代码并尝试单元测试。 这不是不可能的,但要么是不平凡的,要么需要一些复制粘贴来完成它。 protected void buttonClick(object sender, EventArgs e) { string currUser = User.Identity.Name.ToString().Trim() .Substring(User.Identity.Name.ToString().Trim() .Ind ...
  • 毫无疑问,TestFX是JavaFX应用程序的最佳(也是唯一)测试框架。 最新版本标记为4.0.5-alpha但它非常实用且有用。 alpha标签的原因主要与类上缺少的Javadocs以及4.x系列中添加的一些实验性功能有关。 在4.0.4-alpha和4.0.5-alpha之间进行了大量文档更新。 TestFX is without a doubt the best (and only) testing framework for JavaFX applications. The latest versi ...
  • 通常情况下,你应该将请求对象注入类中(通过构造函数参数传递它)并删除硬依赖。 但在你的情况下,没有请求对象开始,你可以用模拟替换。 这就是静态方法的问题。 如果你想编写单元测试,这个Httpful库似乎不是一个好选择。 我看到两个选项: 使用一个不同的,更适合测试的库,如Guzzle 如果那是不可能的,写一个薄的包装器,像这样: class HttpfulClient { public function createGetRequest($url) { return \Htt ...
  • 就个人而言,我发现使用依赖接口可以改进设计。 它清楚地表明了您所依赖的内容,而不仅仅是实现类碰巧暴露的公共和内部方法。 请注意,这并不意味着每个类都需要有一个接口......只是那些您希望充当依赖关系的接口。 例如,我不会为主要是“简单数据”或异常的类型创建接口。 但是如果一个类在某些方面充当“服务”,那么界面感觉是合适的。 如果有一种表达界面的简单方法而不是单独的文件会很好,但从概念上讲我觉得它很干净。 (这个观点让我有点过时了,我意识到,但这有助于我理解我的设计,至少:) Personally I fi ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)